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

Commit 2e637ce2 authored by Wonsik Kim's avatar Wonsik Kim
Browse files

CCodec: do not assume exactly one buffer per worklet

Bug: 72419260
Test: setprop debug.stagefright.ccodec yes
Test: stagefright -S -N c2.google.avc.decoder /sdcard/a.mp4
Test: stagefright -ao -N c2.google.aac.decoder /sdcard/a.mp4
Test: audioloop -N c2.google.aac.encoder -M audio/mp4a-latm
Test: screenrecord --codec-name c2.google.avc.encoder /sdcard/record.mp4
Change-Id: Ifb5deecc31faf9f1d550b454998edd0ea25364aa
parent 8434aabf
Loading
Loading
Loading
Loading
+18 −11
Original line number Diff line number Diff line
@@ -1271,7 +1271,8 @@ void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {

    // NOTE: MediaCodec usage supposedly have only one worklet
    if (work->worklets.size() != 1u) {
        ALOGE("incorrect number of worklets: %zu", work->worklets.size());
        ALOGE("onWorkDone: incorrect number of worklets: %zu",
                work->worklets.size());
        mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
        return;
    }
@@ -1281,18 +1282,24 @@ void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {
        // Discard frames from previous generation.
        return;
    }
    std::shared_ptr<C2Buffer> buffer;
    // NOTE: MediaCodec usage supposedly have only one output stream.
    if (worklet->output.buffers.size() != 1u) {
        ALOGE("incorrect number of output buffers: %zu", worklet->output.buffers.size());
    if (worklet->output.buffers.size() > 1u) {
        ALOGE("onWorkDone: incorrect number of output buffers: %zu",
                worklet->output.buffers.size());
        mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
        return;
    } else if (worklet->output.buffers.size() == 1u) {
        buffer = worklet->output.buffers[0];
        if (!buffer) {
            ALOGW("onWorkDone: nullptr found in buffers; ignored.");
        }
    }

    const std::shared_ptr<C2Buffer> &buffer = worklet->output.buffers[0];
    const C2StreamCsdInfo::output *csdInfo = nullptr;
    for (const std::unique_ptr<C2Param> &info : worklet->output.configUpdate) {
        if (info->coreIndex() == C2StreamCsdInfo::output::CORE_INDEX) {
            ALOGV("csd found");
            ALOGV("onWorkDone: csd found");
            csdInfo = static_cast<const C2StreamCsdInfo::output *>(info.get());
        }
    }
@@ -1300,7 +1307,7 @@ void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {
    int32_t flags = 0;
    if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) {
        flags |= MediaCodec::BUFFER_FLAG_EOS;
        ALOGV("output EOS");
        ALOGV("onWorkDone: output EOS");
    }

    sp<MediaCodecBuffer> outBuffer;
@@ -1310,13 +1317,13 @@ void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {
        if ((*buffers)->registerCsd(csdInfo, &index, &outBuffer)) {
            outBuffer->meta()->setInt64("timeUs", worklet->output.ordinal.timestamp.peek());
            outBuffer->meta()->setInt32("flags", flags | MediaCodec::BUFFER_FLAG_CODECCONFIG);
            ALOGV("csd index = %zu", index);
            ALOGV("onWorkDone: csd index = %zu", index);

            buffers.unlock();
            mCallback->onOutputBufferAvailable(index, outBuffer);
            buffers.lock();
        } else {
            ALOGE("unable to register csd");
            ALOGE("onWorkDone: unable to register csd");
            buffers.unlock();
            mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
            buffers.lock();
@@ -1325,7 +1332,7 @@ void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {
    }

    if (!buffer && !flags) {
        ALOGV("Not reporting output buffer");
        ALOGV("onWorkDone: Not reporting output buffer");
        return;
    }

@@ -1347,7 +1354,7 @@ void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {
    {
        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
        if (!(*buffers)->registerBuffer(buffer, &index, &outBuffer)) {
            ALOGE("unable to register output buffer");
            ALOGE("onWorkDone: unable to register output buffer");
            buffers.unlock();
            mOnError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
            buffers.lock();
@@ -1357,7 +1364,7 @@ void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {

    outBuffer->meta()->setInt64("timeUs", worklet->output.ordinal.timestamp.peek());
    outBuffer->meta()->setInt32("flags", flags);
    ALOGV("out buffer index = %zu", index);
    ALOGV("onWorkDone: out buffer index = %zu", index);
    mCallback->onOutputBufferAvailable(index, outBuffer);
}

+0 −2
Original line number Diff line number Diff line
@@ -375,7 +375,6 @@ void C2SoftAac::process(

        work->worklets.front()->output.ordinal = work->input.ordinal;
        work->worklets.front()->output.buffers.clear();
        work->worklets.front()->output.buffers.push_back(nullptr);

        return;
    }
@@ -602,7 +601,6 @@ c2_status_t C2SoftAac::drainInternal(
        auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
            work->worklets.front()->output.flags = work->input.flags;
            work->worklets.front()->output.buffers.clear();
            work->worklets.front()->output.buffers.emplace_back(nullptr);
            work->worklets.front()->output.ordinal = work->input.ordinal;
            work->workletsProcessed = 1u;
        };
+0 −2
Original line number Diff line number Diff line
@@ -344,8 +344,6 @@ void C2SoftAacEnc::process(
    if (nOutputBytes) {
        work->worklets.front()->output.buffers.push_back(
                createLinearBuffer(block, 0, nOutputBytes));
    } else {
        work->worklets.front()->output.buffers.emplace_back(nullptr);
    }

#if 0
+0 −1
Original line number Diff line number Diff line
@@ -211,7 +211,6 @@ void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
    }
    work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
    work->worklets.front()->output.buffers.clear();
    work->worklets.front()->output.buffers.emplace_back(nullptr);
    work->worklets.front()->output.ordinal = work->input.ordinal;
    work->workletsProcessed = 1u;
}