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

Commit 532d2ac5 authored by James Dong's avatar James Dong Committed by Android (Google) Code Review
Browse files

Merge "Only check the codec specific data when the output buffer contains...

Merge "Only check the codec specific data when the output buffer contains kKeyIsCodecConfig in MP4 writer" into gingerbread
parents e967ee49 f3b7859f
Loading
Loading
Loading
Loading
+6 −85
Original line number Diff line number Diff line
@@ -1377,91 +1377,6 @@ void MPEG4Writer::Track::threadEntry() {

            mGotAllCodecSpecificData = true;
            continue;
        } else if (!mGotAllCodecSpecificData &&
                count == 1 && mIsMPEG4 && mCodecSpecificData == NULL) {
            // The TI mpeg4 encoder does not properly set the
            // codec-specific-data flag.

            const uint8_t *data =
                (const uint8_t *)buffer->data() + buffer->range_offset();

            const size_t size = buffer->range_length();

            size_t offset = 0;
            while (offset + 3 < size) {
                if (data[offset] == 0x00 && data[offset + 1] == 0x00
                    && data[offset + 2] == 0x01 && data[offset + 3] == 0xb6) {
                    break;
                }

                ++offset;
            }

            // CHECK(offset + 3 < size);
            if (offset + 3 >= size) {
                // XXX assume the entire first chunk of data is the codec specific
                // data.
                offset = size;
            }

            mCodecSpecificDataSize = offset;
            mCodecSpecificData = malloc(offset);
            memcpy(mCodecSpecificData, data, offset);

            buffer->set_range(buffer->range_offset() + offset, size - offset);

            if (size == offset) {
                buffer->release();
                buffer = NULL;

                continue;
            }

            mGotAllCodecSpecificData = true;
        } else if (!mGotAllCodecSpecificData && mIsAvc && count < 3) {
            // The TI video encoder does not flag codec specific data
            // as such and also splits up SPS and PPS across two buffers.

            const uint8_t *data =
                (const uint8_t *)buffer->data() + buffer->range_offset();

            size_t size = buffer->range_length();

            CHECK(count == 2 || mCodecSpecificData == NULL);

            size_t offset = mCodecSpecificDataSize;
            mCodecSpecificDataSize += size + 4;
            mCodecSpecificData =
                realloc(mCodecSpecificData, mCodecSpecificDataSize);

            memcpy((uint8_t *)mCodecSpecificData + offset,
                   "\x00\x00\x00\x01", 4);

            memcpy((uint8_t *)mCodecSpecificData + offset + 4, data, size);

            buffer->release();
            buffer = NULL;

            if (count == 2) {
                void *tmp = mCodecSpecificData;
                size = mCodecSpecificDataSize;
                mCodecSpecificData = NULL;
                mCodecSpecificDataSize = 0;

                status_t err = makeAVCCodecSpecificData(
                        (const uint8_t *)tmp, size);
                free(tmp);
                tmp = NULL;
                CHECK_EQ(OK, err);

                mGotAllCodecSpecificData = true;
            }

            continue;
        }

        if (!mGotAllCodecSpecificData) {
            mGotAllCodecSpecificData = true;
        }

        // Make a deep copy of the MediaBuffer and Metadata and release
@@ -1962,6 +1877,8 @@ void MPEG4Writer::Track::writeTrackHeader(
                  mOwner->writeInt32(samplerate << 16);
                  if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
                    mOwner->beginBox("esds");
                        CHECK(mCodecSpecificData);
                        CHECK(mCodecSpecificDataSize > 0);

                        mOwner->writeInt32(0);     // version=0, flags=0
                        mOwner->writeInt8(0x03);   // ES_DescrTag
@@ -2039,6 +1956,8 @@ void MPEG4Writer::Track::writeTrackHeader(
                  mOwner->writeInt16(0x18);        // depth
                  mOwner->writeInt16(-1);          // predefined

                  CHECK(mCodecSpecificData);
                  CHECK(mCodecSpecificDataSize > 0);
                  CHECK(23 + mCodecSpecificDataSize < 128);

                  if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
@@ -2086,6 +2005,8 @@ void MPEG4Writer::Track::writeTrackHeader(

                      mOwner->endBox();  // d263
                  } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
                      CHECK(mCodecSpecificData);
                      CHECK(mCodecSpecificDataSize > 0);
                      mOwner->beginBox("avcC");
                        mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
                      mOwner->endBox();  // avcC
+22 −7
Original line number Diff line number Diff line
@@ -337,14 +337,18 @@ status_t AVCEncoder::read(

    MediaBuffer *outputBuffer;
    CHECK_EQ(OK, mGroup->acquire_buffer(&outputBuffer));
    uint8_t *outPtr = (uint8_t *) outputBuffer->data();
    uint32_t dataLength = outputBuffer->size();

    // Add 4 bytes for the start code 0x00000001
    uint8_t *outPtr = (uint8_t *) outputBuffer->data() + 4;
    uint32_t dataLength = outputBuffer->size() - 4;

    int32_t type;
    AVCEnc_Status encoderStatus = AVCENC_SUCCESS;

    // Return SPS and PPS for the first two buffers
    if (!mSpsPpsHeaderReceived) {
    // Combine SPS and PPS and place them in the very first output buffer
    // SPS and PPS are separated by start code 0x00000001
    // Assume that we have exactly one SPS and exactly one PPS.
    while (!mSpsPpsHeaderReceived && mNumInputFrames <= 0) {
        encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type);
        if (encoderStatus == AVCENC_WRONG_STATE) {
            mSpsPpsHeaderReceived = true;
@@ -352,11 +356,22 @@ status_t AVCEncoder::read(
        } else {
            switch (type) {
                case AVC_NALTYPE_SPS:
                    ++mNumInputFrames;
                    memcpy(outputBuffer->data(), "\x00\x00\x00\x01", 4);
                    outputBuffer->set_range(0, dataLength + 4);
                    outPtr += (dataLength + 4);  // 4 bytes for next start code
                    dataLength = outputBuffer->size() -
                            (outputBuffer->range_length() + 4);
                    break;
                case AVC_NALTYPE_PPS:
                    LOGV("%s received",
                            (type == AVC_NALTYPE_SPS)? "SPS": "PPS");
                    ++mNumInputFrames;
                    outputBuffer->set_range(0, dataLength);
                    memcpy(((uint8_t *) outputBuffer->data()) +
                            outputBuffer->range_length(),
                            "\x00\x00\x00\x01", 4);
                    outputBuffer->set_range(0,
                            dataLength + outputBuffer->range_length() + 4);
                    outputBuffer->meta_data()->setInt32(kKeyIsCodecConfig, 1);
                    outputBuffer->meta_data()->setInt64(kKeyTime, 0);
                    *out = outputBuffer;
                    return OK;
                default: