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

Commit 55f8aee5 authored by Andreas Huber's avatar Andreas Huber
Browse files

Make sure we drain the avc software decoder's output queue once we run out of input data.

Change-Id: I3d92ebae4951b618a6dfcf42936cc4c63d4de539
parent eaa2cabf
Loading
Loading
Loading
Loading
+53 −43
Original line number Diff line number Diff line
@@ -232,6 +232,53 @@ static void findNALFragment(
    }
}

MediaBuffer *AVCDecoder::drainOutputBuffer() {
    int32_t index;
    int32_t Release;
    AVCFrameIO Output;
    Output.YCbCr[0] = Output.YCbCr[1] = Output.YCbCr[2] = NULL;
    AVCDec_Status status = PVAVCDecGetOutput(mHandle, &index, &Release, &Output);

    if (status != AVCDEC_SUCCESS) {
        LOGV("PVAVCDecGetOutput returned error %d", status);
        return NULL;
    }

    CHECK(index >= 0);
    CHECK(index < (int32_t)mFrames.size());

    MediaBuffer *mbuf = mFrames.editItemAt(index);

    bool skipFrame = false;

    if (mTargetTimeUs >= 0) {
        int64_t timeUs;
        CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
        CHECK(timeUs <= mTargetTimeUs);

        if (timeUs < mTargetTimeUs) {
            // We're still waiting for the frame with the matching
            // timestamp and we won't return the current one.
            skipFrame = true;

            LOGV("skipping frame at %lld us", timeUs);
        } else {
            LOGV("found target frame at %lld us", timeUs);

            mTargetTimeUs = -1;
        }
    }

    if (!skipFrame) {
        mbuf->set_range(0, mbuf->size());
        mbuf->add_ref();

        return mbuf;
    }

    return new MediaBuffer(0);
}

status_t AVCDecoder::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;
@@ -279,7 +326,8 @@ status_t AVCDecoder::read(
                seekOptions.clearSeekTo();

                if (err != OK) {
                    return err;
                    *out = drainOutputBuffer();
                    return (*out == NULL)  ? err : (status_t)OK;
                }

                if (mInputBuffer->range_length() > 0) {
@@ -415,51 +463,12 @@ status_t AVCDecoder::read(
                        fragSize);

                if (res == AVCDEC_PICTURE_OUTPUT_READY) {
                    int32_t index;
                    int32_t Release;
                    AVCFrameIO Output;
                    Output.YCbCr[0] = Output.YCbCr[1] = Output.YCbCr[2] = NULL;

                    AVCDec_Status status =
                        PVAVCDecGetOutput(mHandle, &index, &Release, &Output);

                    if (status != AVCDEC_SUCCESS) {
                        LOGV("PVAVCDecGetOutput returned error %d", status);
                    MediaBuffer *mbuf = drainOutputBuffer();
                    if (mbuf == NULL) {
                        break;
                    }

                    CHECK(index >= 0);
                    CHECK(index < (int32_t)mFrames.size());

                    MediaBuffer *mbuf = mFrames.editItemAt(index);

                    bool skipFrame = false;

                    if (mTargetTimeUs >= 0) {
                        int64_t timeUs;
                        CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
                        CHECK(timeUs <= mTargetTimeUs);

                        if (timeUs < mTargetTimeUs) {
                            // We're still waiting for the frame with the matching
                            // timestamp and we won't return the current one.
                            skipFrame = true;

                            LOGV("skipping frame at %lld us", timeUs);
                        } else {
                            LOGV("found target frame at %lld us", timeUs);

                            mTargetTimeUs = -1;
                        }
                    }

                    if (!skipFrame) {
                    *out = mbuf;
                        (*out)->set_range(0, (*out)->size());
                        (*out)->add_ref();
                    } else {
                        *out = new MediaBuffer(0);
                    }

                    // Do _not_ release input buffer yet.

@@ -496,6 +505,7 @@ status_t AVCDecoder::read(

            case AVC_NALTYPE_AUD:
            case AVC_NALTYPE_FILL:
            case AVC_NALTYPE_EOSEQ:
            {
                *out = new MediaBuffer(0);

+2 −0
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@ private:

    void releaseFrames();

    MediaBuffer *drainOutputBuffer();

    AVCDecoder(const AVCDecoder &);
    AVCDecoder &operator=(const AVCDecoder &);
};