Merge "Support more MPEG4-LATM audio functionality."
This commit is contained in:
committed by
Android (Google) Code Review
commit
dc94eea3f4
@@ -31,6 +31,8 @@ struct ABitReader {
|
||||
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 @@ private:
|
||||
size_t mNumBitsLeft;
|
||||
|
||||
void fillReservoir();
|
||||
void putBits(uint32_t x, size_t n);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
|
||||
};
|
||||
|
||||
@@ -90,9 +90,7 @@ size_t ABitReader::numBitsLeft() const {
|
||||
}
|
||||
|
||||
const uint8_t *ABitReader::data() const {
|
||||
CHECK_EQ(mNumBitsLeft % 8, 0u);
|
||||
|
||||
return mData - mNumBitsLeft / 8;
|
||||
return mData - (mNumBitsLeft + 7) / 8;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -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 @@ static status_t parseGASpecificConfig(
|
||||
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 @@ static status_t parseAudioSpecificConfig(ABitReader *bits) {
|
||||
}
|
||||
}
|
||||
|
||||
#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 @@ static status_t parseAudioSpecificConfig(ABitReader *bits) {
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -214,6 +256,7 @@ static status_t parseStreamMuxConfig(
|
||||
ABitReader *bits,
|
||||
unsigned *numSubFrames,
|
||||
unsigned *frameLengthType,
|
||||
ssize_t *fixedFrameLength,
|
||||
bool *otherDataPresent,
|
||||
unsigned *otherDataLenBits) {
|
||||
unsigned audioMuxVersion = bits->getBits(1);
|
||||
@@ -242,12 +285,14 @@ static status_t parseStreamMuxConfig(
|
||||
|
||||
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 @@ static status_t parseStreamMuxConfig(
|
||||
|
||||
case 1:
|
||||
{
|
||||
/* unsigned frameLength = */bits->getBits(9);
|
||||
*fixedFrameLength = bits->getBits(9);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
// reserved
|
||||
TRESPASS();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -338,9 +390,21 @@ sp<ABuffer> AMPEG4AudioAssembler::removeLATMFraming(const sp<ABuffer> &buffer) {
|
||||
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 @@ AMPEG4AudioAssembler::AMPEG4AudioAssembler(
|
||||
ABitReader bits(config->data(), config->size());
|
||||
status_t err = parseStreamMuxConfig(
|
||||
&bits, &mNumSubFrames, &mFrameLengthType,
|
||||
&mFixedFrameLength,
|
||||
&mOtherDataPresent, &mOtherDataLenBits);
|
||||
|
||||
CHECK_EQ(err, (status_t)NO_ERROR);
|
||||
|
||||
@@ -46,6 +46,7 @@ private:
|
||||
bool mMuxConfigPresent;
|
||||
unsigned mNumSubFrames;
|
||||
unsigned mFrameLengthType;
|
||||
ssize_t mFixedFrameLength;
|
||||
bool mOtherDataPresent;
|
||||
unsigned mOtherDataLenBits;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user