Merge "OggWriter: Support format without CSD for opus" into qt-dev
diff --git a/media/libstagefright/OggWriter.cpp b/media/libstagefright/OggWriter.cpp
index cb87b55..b738fef 100644
--- a/media/libstagefright/OggWriter.cpp
+++ b/media/libstagefright/OggWriter.cpp
@@ -52,6 +52,7 @@
OggWriter::OggWriter(int fd)
: mFd(dup(fd)),
+ mHaveAllCodecSpecificData(false),
mInitCheck(mFd < 0 ? NO_INIT : OK) {
// empty
}
@@ -115,17 +116,26 @@
mSampleRate = sampleRate;
uint32_t type;
- const void *header_data;
- size_t packet_size;
+ const void *header_data = NULL;
+ size_t packet_size = 0;
+
if (!source->getFormat()->findData(kKeyOpusHeader, &type, &header_data, &packet_size)) {
- ALOGE("opus header not found");
- return UNKNOWN_ERROR;
+ ALOGV("opus header not found in format");
+ } else if (header_data && packet_size) {
+ writeOggHeaderPackets((unsigned char *)header_data, packet_size);
+ } else {
+ ALOGD("ignoring incomplete opus header data in format");
}
+ mSource = source;
+ return OK;
+}
+
+status_t OggWriter::writeOggHeaderPackets(unsigned char *buf, size_t size) {
ogg_packet op;
ogg_page og;
- op.packet = (unsigned char *)header_data;
- op.bytes = packet_size;
+ op.packet = buf;
+ op.bytes = size;
op.b_o_s = 1;
op.e_o_s = 0;
op.granulepos = 0;
@@ -169,8 +179,8 @@
write(mFd, og.body, og.body_len);
}
- mSource = source;
free(comments);
+ mHaveAllCodecSpecificData = true;
return OK;
}
@@ -301,12 +311,35 @@
&& isCodecSpecific)
|| IsOpusHeader((uint8_t*)buffer->data() + buffer->range_offset(),
buffer->range_length())) {
- ALOGV("Drop codec specific info buffer");
+ if (mHaveAllCodecSpecificData == false) {
+ size_t opusHeadSize = 0;
+ size_t codecDelayBufSize = 0;
+ size_t seekPreRollBufSize = 0;
+ void *opusHeadBuf = NULL;
+ void *codecDelayBuf = NULL;
+ void *seekPreRollBuf = NULL;
+ GetOpusHeaderBuffers((uint8_t*)buffer->data() + buffer->range_offset(),
+ buffer->range_length(), &opusHeadBuf,
+ &opusHeadSize, &codecDelayBuf,
+ &codecDelayBufSize, &seekPreRollBuf,
+ &seekPreRollBufSize);
+ writeOggHeaderPackets((unsigned char *)opusHeadBuf, opusHeadSize);
+ } else {
+ ALOGV("ignoring later copy of CSD contained in info buffer");
+ }
buffer->release();
buffer = nullptr;
continue;
}
+ if (mHaveAllCodecSpecificData == false) {
+ ALOGE("Did not get valid opus header before first sample data");
+ buffer->release();
+ buffer = nullptr;
+ err = ERROR_MALFORMED;
+ break;
+ }
+
int64_t timestampUs;
CHECK(buffer->meta_data().findInt64(kKeyTime, ×tampUs));
if (timestampUs > mEstimatedDurationUs) {
diff --git a/media/libstagefright/include/media/stagefright/OggWriter.h b/media/libstagefright/include/media/stagefright/OggWriter.h
index e3837cd..1a0a1d2 100644
--- a/media/libstagefright/include/media/stagefright/OggWriter.h
+++ b/media/libstagefright/include/media/stagefright/OggWriter.h
@@ -43,6 +43,7 @@
private:
int mFd;
+ bool mHaveAllCodecSpecificData;
status_t mInitCheck;
sp<MediaSource> mSource;
bool mStarted = false;
@@ -66,6 +67,8 @@
OggWriter(const OggWriter&);
OggWriter& operator=(const OggWriter&);
+
+ status_t writeOggHeaderPackets(unsigned char *buf, size_t size);
};
} // namespace android