Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8c7c6dc4 authored by Andreas Huber's avatar Andreas Huber
Browse files

Support more MPEG4-LATM audio functionality.

related-to-bug: 3474610

Change-Id: I6dab40e8b465922c62be9ee7f168718822c6caac
Now skipping extra header that the spec claimed shouldn't be present in LATM...
parent 03901913
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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);
};
+1 −3
Original line number Diff line number Diff line
@@ -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
+74 −9
Original line number Diff line number Diff line
@@ -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,10 +390,22 @@ sp<ABuffer> AMPEG4AudioAssembler::removeLATMFraming(const sp<ABuffer> &buffer) {
                break;
            }

            case 2:
            {
                // reserved

                TRESPASS();
                break;
            }

            default:
                TRESPASS();  // XXX to be implemented
            {
                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);
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ private:
    bool mMuxConfigPresent;
    unsigned mNumSubFrames;
    unsigned mFrameLengthType;
    ssize_t mFixedFrameLength;
    bool mOtherDataPresent;
    unsigned mOtherDataLenBits;