Merge "Support more MPEG4-LATM audio functionality."
diff --git a/include/media/stagefright/foundation/ABitReader.h b/include/media/stagefright/foundation/ABitReader.h
index 5135211..5510b12 100644
--- a/include/media/stagefright/foundation/ABitReader.h
+++ b/include/media/stagefright/foundation/ABitReader.h
@@ -31,6 +31,8 @@
uint32_t getBits(size_t n);
void skipBits(size_t n);
+ void putBits(uint32_t x, size_t n);
+
size_t numBitsLeft() const;
const uint8_t *data() const;
@@ -43,7 +45,6 @@
size_t mNumBitsLeft;
void fillReservoir();
- void putBits(uint32_t x, size_t n);
DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
};
diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/libstagefright/foundation/ABitReader.cpp
index 24c8df8..f07dd4f 100644
--- a/media/libstagefright/foundation/ABitReader.cpp
+++ b/media/libstagefright/foundation/ABitReader.cpp
@@ -90,9 +90,7 @@
}
const uint8_t *ABitReader::data() const {
- CHECK_EQ(mNumBitsLeft % 8, 0u);
-
- return mData - mNumBitsLeft / 8;
+ return mData - (mNumBitsLeft + 7) / 8;
}
} // namespace android
diff --git a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
index 8bfe285..11d9c22 100644
--- a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AMPEG4AudioAssembler"
+
#include "AMPEG4AudioAssembler.h"
#include "ARTPSource.h"
@@ -139,7 +142,10 @@
return OK;
}
-static status_t parseAudioSpecificConfig(ABitReader *bits) {
+static status_t parseAudioSpecificConfig(ABitReader *bits, sp<ABuffer> *asc) {
+ const uint8_t *dataStart = bits->data();
+ size_t totalNumBits = bits->numBitsLeft();
+
unsigned audioObjectType;
CHECK_EQ(parseAudioObjectType(bits, &audioObjectType), (status_t)OK);
@@ -185,13 +191,13 @@
}
}
-#if 0
- // This is not supported here as the upper layers did not explicitly
- // signal the length of AudioSpecificConfig.
-
if (extensionAudioObjectType != 5 && bits->numBitsLeft() >= 16) {
+ size_t numBitsLeftAtStart = bits->numBitsLeft();
+
unsigned syncExtensionType = bits->getBits(11);
if (syncExtensionType == 0x2b7) {
+ LOGI("found syncExtension");
+
CHECK_EQ(parseAudioObjectType(bits, &extensionAudioObjectType),
(status_t)OK);
@@ -203,9 +209,45 @@
/* unsigned extensionSamplingFrequency = */bits->getBits(24);
}
}
+
+ size_t numBitsInExtension =
+ numBitsLeftAtStart - bits->numBitsLeft();
+
+ if (numBitsInExtension & 7) {
+ // Apparently an extension is always considered an even
+ // multiple of 8 bits long.
+
+ LOGI("Skipping %d bits after sync extension",
+ 8 - (numBitsInExtension & 7));
+
+ bits->skipBits(8 - (numBitsInExtension & 7));
+ }
+ } else {
+ bits->putBits(syncExtensionType, 11);
}
}
-#endif
+
+ if (asc != NULL) {
+ size_t bitpos = totalNumBits & 7;
+
+ ABitReader bs(dataStart, (totalNumBits + 7) / 8);
+
+ totalNumBits -= bits->numBitsLeft();
+
+ size_t numBytes = (totalNumBits + 7) / 8;
+
+ *asc = new ABuffer(numBytes);
+
+ if (bitpos & 7) {
+ bs.skipBits(8 - (bitpos & 7));
+ }
+
+ uint8_t *dstPtr = (*asc)->data();
+ while (numBytes > 0) {
+ *dstPtr++ = bs.getBits(8);
+ --numBytes;
+ }
+ }
return OK;
}
@@ -214,6 +256,7 @@
ABitReader *bits,
unsigned *numSubFrames,
unsigned *frameLengthType,
+ ssize_t *fixedFrameLength,
bool *otherDataPresent,
unsigned *otherDataLenBits) {
unsigned audioMuxVersion = bits->getBits(1);
@@ -242,12 +285,14 @@
if (audioMuxVersion == 0) {
// AudioSpecificConfig
- CHECK_EQ(parseAudioSpecificConfig(bits), (status_t)OK);
+ CHECK_EQ(parseAudioSpecificConfig(bits, NULL /* asc */), (status_t)OK);
} else {
TRESPASS(); // XXX to be implemented
}
*frameLengthType = bits->getBits(3);
+ *fixedFrameLength = -1;
+
switch (*frameLengthType) {
case 0:
{
@@ -260,7 +305,14 @@
case 1:
{
- /* unsigned frameLength = */bits->getBits(9);
+ *fixedFrameLength = bits->getBits(9);
+ break;
+ }
+
+ case 2:
+ {
+ // reserved
+ TRESPASS();
break;
}
@@ -338,9 +390,21 @@
break;
}
- default:
- TRESPASS(); // XXX to be implemented
+ case 2:
+ {
+ // reserved
+
+ TRESPASS();
break;
+ }
+
+ default:
+ {
+ CHECK_GE(mFixedFrameLength, 0);
+
+ payloadLength = mFixedFrameLength;
+ break;
+ }
}
CHECK_LE(offset + payloadLength, buffer->size());
@@ -393,6 +457,7 @@
ABitReader bits(config->data(), config->size());
status_t err = parseStreamMuxConfig(
&bits, &mNumSubFrames, &mFrameLengthType,
+ &mFixedFrameLength,
&mOtherDataPresent, &mOtherDataLenBits);
CHECK_EQ(err, (status_t)NO_ERROR);
diff --git a/media/libstagefright/rtsp/AMPEG4AudioAssembler.h b/media/libstagefright/rtsp/AMPEG4AudioAssembler.h
index 9cef94c..1361cd2 100644
--- a/media/libstagefright/rtsp/AMPEG4AudioAssembler.h
+++ b/media/libstagefright/rtsp/AMPEG4AudioAssembler.h
@@ -46,6 +46,7 @@
bool mMuxConfigPresent;
unsigned mNumSubFrames;
unsigned mFrameLengthType;
+ ssize_t mFixedFrameLength;
bool mOtherDataPresent;
unsigned mOtherDataLenBits;