Merge "Support more MPEG4-LATM audio functionality."

This commit is contained in:
Andreas Huber
2011-02-22 13:51:22 -08:00
committed by Android (Google) Code Review
4 changed files with 79 additions and 14 deletions

View File

@@ -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);
};

View File

@@ -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

View File

@@ -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);

View File

@@ -46,6 +46,7 @@ private:
bool mMuxConfigPresent;
unsigned mNumSubFrames;
unsigned mFrameLengthType;
ssize_t mFixedFrameLength;
bool mOtherDataPresent;
unsigned mOtherDataLenBits;