Merge "MPEG4Writer: Large CodecSpecificData in MP4 ESDS box"
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 1ec419a..2f13dc9 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -72,6 +72,7 @@
static const int64_t kInitialDelayTimeUs = 700000LL;
static const int64_t kMaxMetadataSize = 0x4000000LL; // 64MB max per-frame metadata size
static const int64_t kMaxCttsOffsetTimeUs = 30 * 60 * 1000000LL; // 30 minutes
+static const size_t kESDSScratchBufferSize = 10; // kMaxAtomSize in Mpeg4Extractor 64MB
static const char kMetaKey_Version[] = "com.android.version";
static const char kMetaKey_Manufacturer[] = "com.android.manufacturer";
@@ -3882,22 +3883,52 @@
mOwner->endBox();
}
+static void generateEsdsSize(size_t dataLength, size_t* sizeGenerated, uint8_t* buffer) {
+ size_t offset = 0, cur = 0;
+ size_t more = 0x00;
+ *sizeGenerated = 0;
+ /* Start with the LSB(7 bits) of dataLength and build the byte sequence upto MSB.
+ * Continuation flag(most significant bit) will be set on the first N-1 bytes.
+ */
+ do {
+ buffer[cur++] = (dataLength & 0x7f) | more;
+ dataLength >>= 7;
+ more = 0x80;
+ ++(*sizeGenerated);
+ } while (dataLength > 0u);
+ --cur;
+ // Reverse the newly formed byte sequence.
+ while (cur > offset) {
+ uint8_t tmp = buffer[cur];
+ buffer[cur--] = buffer[offset];
+ buffer[offset++] = tmp;
+ }
+}
+
void MPEG4Writer::Track::writeMp4aEsdsBox() {
- mOwner->beginBox("esds");
CHECK(mCodecSpecificData);
CHECK_GT(mCodecSpecificDataSize, 0u);
- // Make sure all sizes encode to a single byte.
- CHECK_LT(mCodecSpecificDataSize + 23, 128u);
+ uint8_t sizeESDBuffer[kESDSScratchBufferSize];
+ uint8_t sizeDCDBuffer[kESDSScratchBufferSize];
+ uint8_t sizeDSIBuffer[kESDSScratchBufferSize];
+ size_t sizeESD = 0;
+ size_t sizeDCD = 0;
+ size_t sizeDSI = 0;
+ generateEsdsSize(mCodecSpecificDataSize, &sizeDSI, sizeDSIBuffer);
+ generateEsdsSize(mCodecSpecificDataSize + sizeDSI + 14, &sizeDCD, sizeDCDBuffer);
+ generateEsdsSize(mCodecSpecificDataSize + sizeDSI + sizeDCD + 21, &sizeESD, sizeESDBuffer);
+
+ mOwner->beginBox("esds");
mOwner->writeInt32(0); // version=0, flags=0
mOwner->writeInt8(0x03); // ES_DescrTag
- mOwner->writeInt8(23 + mCodecSpecificDataSize);
+ mOwner->write(sizeESDBuffer, sizeESD);
mOwner->writeInt16(0x0000);// ES_ID
mOwner->writeInt8(0x00);
mOwner->writeInt8(0x04); // DecoderConfigDescrTag
- mOwner->writeInt8(15 + mCodecSpecificDataSize);
+ mOwner->write(sizeDCDBuffer, sizeDCD);
mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2
mOwner->writeInt8(0x15); // streamType AudioStream
@@ -3912,7 +3943,7 @@
mOwner->writeInt32(avgBitrate);
mOwner->writeInt8(0x05); // DecoderSpecificInfoTag
- mOwner->writeInt8(mCodecSpecificDataSize);
+ mOwner->write(sizeDSIBuffer, sizeDSI);
mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
static const uint8_t kData2[] = {
@@ -3929,20 +3960,27 @@
CHECK(mCodecSpecificData);
CHECK_GT(mCodecSpecificDataSize, 0u);
- // Make sure all sizes encode to a single byte.
- CHECK_LT(23 + mCodecSpecificDataSize, 128u);
+ uint8_t sizeESDBuffer[kESDSScratchBufferSize];
+ uint8_t sizeDCDBuffer[kESDSScratchBufferSize];
+ uint8_t sizeDSIBuffer[kESDSScratchBufferSize];
+ size_t sizeESD = 0;
+ size_t sizeDCD = 0;
+ size_t sizeDSI = 0;
+ generateEsdsSize(mCodecSpecificDataSize, &sizeDSI, sizeDSIBuffer);
+ generateEsdsSize(mCodecSpecificDataSize + sizeDSI + 14, &sizeDCD, sizeDCDBuffer);
+ generateEsdsSize(mCodecSpecificDataSize + sizeDSI + sizeDCD + 21, &sizeESD, sizeESDBuffer);
mOwner->beginBox("esds");
mOwner->writeInt32(0); // version=0, flags=0
mOwner->writeInt8(0x03); // ES_DescrTag
- mOwner->writeInt8(23 + mCodecSpecificDataSize);
+ mOwner->write(sizeESDBuffer, sizeESD);
mOwner->writeInt16(0x0000); // ES_ID
mOwner->writeInt8(0x1f);
mOwner->writeInt8(0x04); // DecoderConfigDescrTag
- mOwner->writeInt8(15 + mCodecSpecificDataSize);
+ mOwner->write(sizeDCDBuffer, sizeDCD);
mOwner->writeInt8(0x20); // objectTypeIndication ISO/IEC 14492-2
mOwner->writeInt8(0x11); // streamType VisualStream
@@ -3960,7 +3998,7 @@
mOwner->writeInt8(0x05); // DecoderSpecificInfoTag
- mOwner->writeInt8(mCodecSpecificDataSize);
+ mOwner->write(sizeDSIBuffer, sizeDSI);
mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
static const uint8_t kData2[] = {