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

Commit ec910347 authored by Marc Kassis's avatar Marc Kassis
Browse files

Workaround impl in acodec / ccodec

Bug: 234708299
Test: atest DecodeOnlyTest

Change-Id: I293da198837e2bbbc73360e9cfa175643c497387
parent ca8186ef
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1998,6 +1998,12 @@ bool CCodecBufferChannel::handleWork(
        drop = true;
    }

    // Workaround: if C2FrameData::FLAG_DROP_FRAME is not implemented in
    // HAL, the flag is then removed in the corresponding output buffer.
    if (work->input.flags & C2FrameData::FLAG_DROP_FRAME) {
        flags |= BUFFER_FLAG_DECODE_ONLY;
    }

    if (notifyClient && !buffer && !flags) {
        if (mTunneled && drop && outputFormat) {
            ALOGV("[%s] onWorkDone: Keep tunneled, drop frame with format change (%lld)",
+37 −1
Original line number Diff line number Diff line
@@ -6318,6 +6318,7 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
                int32_t isDecodeOnly = 0;
                if (buffer->meta()->findInt32("decode-only", &isDecodeOnly) && isDecodeOnly != 0) {
                    flags |= OMX_BUFFERFLAG_DECODEONLY;
                    mCodec->mDecodeOnlyTimesUs.emplace(timeUs);
                }
                size_t size = buffer->size();
                size_t offset = buffer->offset();
@@ -6642,6 +6643,39 @@ bool ACodec::BaseState::onOMXFillBufferDone(

            info->mData.clear();

            // Workaround: if OMX_BUFFERFLAG_DECODEONLY is not implemented in
            // HAL, the flag is then removed in the corresponding output buffer.

            // for all buffers that were marked as DECODE_ONLY, remove their timestamp
            // if it is smaller than the timestamp of the buffer that was
            // just received
            while (!mCodec->mDecodeOnlyTimesUs.empty() &&
                   *mCodec->mDecodeOnlyTimesUs.begin() < timeUs) {
                    mCodec->mDecodeOnlyTimesUs.erase(mCodec->mDecodeOnlyTimesUs.begin());
            }
            // if OMX_BUFFERFLAG_DECODEONLY is not implemented in HAL, we need to restore the
            // OMX_BUFFERFLAG_DECODEONLY flag to the frames we had saved in the set, the set
            // contains the timestamps of buffers that were marked as DECODE_ONLY by the app
            if (!mCodec->mDecodeOnlyTimesUs.empty() &&
                *mCodec->mDecodeOnlyTimesUs.begin() == timeUs) {
                mCodec->mDecodeOnlyTimesUs.erase(timeUs);
                // If the app queued the last valid buffer as DECODE_ONLY and queued an additional
                // empty buffer as EOS, it's possible that HAL sets the last valid frame as EOS
                // instead and drops the empty buffer. In such a case, we should not add back
                // the OMX_BUFFERFLAG_DECODEONLY flag to it, as doing so will make it so that the
                // app does not receive the EOS buffer, which breaks the contract of EOS buffers
                if (flags & OMX_BUFFERFLAG_EOS) {
                    // Set buffer size to 0, as described by
                    // https://developer.android.com/reference/android/media/MediaCodec.BufferInfo?hl=en#size
                    // a buffer of size 0 should only be used to carry the EOS flag and should
                    // be discarded by the app as it has no data
                    buffer->setRange(0, 0);
                } else {
                    // re-add the OMX_BUFFERFLAG_DECODEONLY flag to the buffer in case it is
                    // not the end of stream buffer
                    flags |= OMX_BUFFERFLAG_DECODEONLY;
                }
            }
            mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags);

            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
@@ -6862,6 +6896,7 @@ void ACodec::UninitializedState::stateEntered() {
    mCodec->mConverter[0].clear();
    mCodec->mConverter[1].clear();
    mCodec->mComponentName.clear();
    mCodec->mDecodeOnlyTimesUs.clear();
}

bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
@@ -8847,6 +8882,7 @@ void ACodec::FlushingState::stateEntered() {
    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());

    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
    mCodec->mDecodeOnlyTimesUs.clear();

    // If we haven't transitioned after 3 seconds, we're probably stuck.
    sp<AMessage> msg = new AMessage(ACodec::kWhatCheckIfStuck, mCodec);
+3 −0
Original line number Diff line number Diff line
@@ -642,6 +642,9 @@ void ACodecBufferChannel::drainThisBuffer(
    if (omxFlags & OMX_BUFFERFLAG_EOS) {
        flags |= MediaCodec::BUFFER_FLAG_EOS;
    }
    if (omxFlags & OMX_BUFFERFLAG_DECODEONLY) {
        flags |= MediaCodec::BUFFER_FLAG_DECODE_ONLY;
    }
    it->mClientBuffer->meta()->setInt32("flags", flags);

    mCallback->onOutputBufferAvailable(
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef A_CODEC_H_
#define A_CODEC_H_

#include <set>
#include <stdint.h>
#include <list>
#include <vector>
@@ -270,6 +271,7 @@ private:
    std::vector<BufferInfo> mBuffers[2];
    bool mPortEOS[2];
    status_t mInputEOSResult;
    std::set<int64_t> mDecodeOnlyTimesUs;

    std::list<sp<AMessage>> mDeferredQueue;