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

Commit c4273482 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Fix mpeg4/h.263 software decoder."

parents 40967d61 2039bd93
Loading
Loading
Loading
Loading
+61 −17
Original line number Diff line number Diff line
@@ -43,8 +43,17 @@ M4vH263Decoder::M4vH263Decoder(const sp<MediaSource> &source)
    memset(mHandle, 0, sizeof(tagvideoDecControls));
    mFormat = new MetaData;
    mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
    CHECK(mSource->getFormat()->findInt32(kKeyWidth, &mWidth));
    CHECK(mSource->getFormat()->findInt32(kKeyHeight, &mHeight));

    // CHECK(mSource->getFormat()->findInt32(kKeyWidth, &mWidth));
    // CHECK(mSource->getFormat()->findInt32(kKeyHeight, &mHeight));

    // We'll ignore the dimension advertised by the source, the decoder
    // appears to require us to always start with the default dimensions
    // of 352 x 288 to operate correctly and later react to changes in
    // the dimensions as needed.
    mWidth = 352;
    mHeight = 288;

    mFormat->setInt32(kKeyWidth, mWidth);
    mFormat->setInt32(kKeyHeight, mHeight);
    mFormat->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
@@ -60,6 +69,20 @@ M4vH263Decoder::~M4vH263Decoder() {
    mHandle = NULL;
}

void M4vH263Decoder::allocateFrames(int32_t width, int32_t height) {
    size_t frameSize =
        (((width + 15) & - 16) * ((height + 15) & - 16) * 3) / 2;

    for (uint32_t i = 0; i < 2; ++i) {
        mFrames[i] = new MediaBuffer(frameSize);
        mFrames[i]->setObserver(this);
    }

    PVSetReferenceYUV(
            mHandle,
            (uint8_t *)mFrames[1]->data());
}

status_t M4vH263Decoder::start(MetaData *) {
    CHECK(!mStarted);

@@ -85,7 +108,8 @@ status_t M4vH263Decoder::start(MetaData *) {

        const void *codec_specific_data;
        size_t codec_specific_data_size;
        esds.getCodecSpecificInfo(&codec_specific_data, &codec_specific_data_size);
        esds.getCodecSpecificInfo(
                &codec_specific_data, &codec_specific_data_size);

        vol_data[0] = (uint8_t *) malloc(codec_specific_data_size);
        memcpy(vol_data[0], codec_specific_data, codec_specific_data_size);
@@ -102,12 +126,14 @@ status_t M4vH263Decoder::start(MetaData *) {
    CHECK_EQ(mode, actualMode);

    PVSetPostProcType((VideoDecControls *) mHandle, 0);
    size_t frameSize = (((mWidth + 15) & - 16) * ((mHeight + 15) & - 16) * 3) / 2;
    for (uint32_t i = 0; i < 2; ++i) {
        mFrames[i] = new MediaBuffer(frameSize);
        mFrames[i]->setObserver(this);

    int32_t width, height;
    PVGetVideoDimensions(mHandle, &width, &height);
    if (mode == H263_MODE && (width == 0 || height == 0)) {
        width = 352;
        height = 288;
    }
    PVSetReferenceYUV(mHandle, (uint8_t *)mFrames[1]->data());
    allocateFrames(width, height);

    mSource->start();

@@ -152,24 +178,41 @@ status_t M4vH263Decoder::read(
        return err;
    }

    uint8_t *bitstream = (uint8_t *) inputBuffer->data() + inputBuffer->range_offset();
    uint8_t *bitstream =
        (uint8_t *) inputBuffer->data() + inputBuffer->range_offset();

    uint32_t timestamp = 0xFFFFFFFF;
    int32_t bufferSize = inputBuffer->range_length();
    uint32_t useExtTimestamp = 0;
    CHECK_EQ(PV_TRUE, PVDecodeVideoFrame(mHandle, &bitstream, &timestamp, &bufferSize,
            &useExtTimestamp,  (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data()));
    if (PVDecodeVideoFrame(
                mHandle, &bitstream, &timestamp, &bufferSize,
                &useExtTimestamp,
                (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data())
            != PV_TRUE) {
        LOGE("failed to decode video frame.");

        inputBuffer->release();
        inputBuffer = NULL;

        return UNKNOWN_ERROR;
    }

    // Check whether video dimension is changed.
    // If so, notify the client about the change.
    int32_t width, height;
    PVGetVideoDimensions(mHandle, &width, &height);
    if (mWidth != width || mHeight != height) {
        mFormat->setInt32(kKeyWidth, width);
        mFormat->setInt32(kKeyHeight, height);
    if (width != mWidth || height != mHeight) {
        ++mNumSamplesOutput;  // The client will never get to see this frame.

        inputBuffer->release();
        inputBuffer = NULL;

        mWidth = width;
        mHeight = height;
        mFormat->setInt32(kKeyWidth, mWidth);
        mFormat->setInt32(kKeyHeight, mHeight);

        return INFO_FORMAT_CHANGED;
    }

    PVSetReferenceYUV(mHandle, (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data());
    *out = mFrames[mNumSamplesOutput & 0x01];
    (*out)->add_ref();

@@ -179,6 +222,7 @@ status_t M4vH263Decoder::read(

    ++mNumSamplesOutput;
    inputBuffer->release();
    inputBuffer = NULL;

    return OK;
}
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ private:

    int64_t mNumSamplesOutput;

    void allocateFrames(int32_t width, int32_t height);
    void releaseFrames();

    M4vH263Decoder(const M4vH263Decoder &);