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

Commit fe5a9f7b authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "C2SoftFlacEnc: Send single frame per output by using cloneAndSend" am:...

Merge "C2SoftFlacEnc: Send single frame per output by using cloneAndSend" am: 71beebd1 am: fb0e1bdf am: b39d0d76

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2605105



Change-Id: Ib7d950224923e920461c86141b35da4f4727b28b
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents e8fd837b b39d0d76
Loading
Loading
Loading
Loading
+60 −15
Original line number Diff line number Diff line
@@ -188,12 +188,6 @@ c2_status_t C2SoftFlacEnc::onFlush_sm() {
    return onStop();
}

static void 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.ordinal = work->input.ordinal;
}

void C2SoftFlacEnc::process(
        const std::unique_ptr<C2Work> &work,
        const std::shared_ptr<C2BlockPool> &pool) {
@@ -245,12 +239,10 @@ void C2SoftFlacEnc::process(
        mWroteHeader = true;
    }

    const uint32_t sampleRate = mIntf->getSampleRate();
    const uint32_t channelCount = mIntf->getChannelCount();
    const bool inputFloat = mIntf->getPcmEncodingInfo() == C2Config::PCM_FLOAT;
    const unsigned sampleSize = inputFloat ? sizeof(float) : sizeof(int16_t);
    const unsigned frameSize = channelCount * sampleSize;
    const uint64_t outTimeStamp = mProcessedSamples * 1000000ll / sampleRate;

    size_t outCapacity = inSize;
    outCapacity += mBlockSize * frameSize;
@@ -270,6 +262,33 @@ void C2SoftFlacEnc::process(
        return;
    }

    class FillWork {
    public:
        FillWork(uint32_t flags, C2WorkOrdinalStruct ordinal,
                 const std::shared_ptr<C2Buffer> &buffer)
            : mFlags(flags), mOrdinal(ordinal), mBuffer(buffer) {}
        ~FillWork() = default;

        void operator()(const std::unique_ptr<C2Work> &work) {
            work->worklets.front()->output.flags = (C2FrameData::flags_t)mFlags;
            work->worklets.front()->output.buffers.clear();
            work->worklets.front()->output.ordinal = mOrdinal;
            work->workletsProcessed = 1u;
            work->result = C2_OK;
            if (mBuffer) {
                work->worklets.front()->output.buffers.push_back(mBuffer);
            }
            ALOGV("timestamp = %lld, index = %lld, w/%s buffer",
                  mOrdinal.timestamp.peekll(), mOrdinal.frameIndex.peekll(),
                  mBuffer ? "" : "o");
        }

    private:
        const uint32_t mFlags;
        const C2WorkOrdinalStruct mOrdinal;
        const std::shared_ptr<C2Buffer> mBuffer;
    };

    mEncoderWriteData = true;
    mEncoderReturnedNbBytes = 0;
    size_t inPos = 0;
@@ -308,14 +327,33 @@ void C2SoftFlacEnc::process(
        mOutputBlock.reset();
        return;
    }
    fillEmptyWork(work);
    if (mEncoderReturnedNbBytes != 0) {
        std::shared_ptr<C2Buffer> buffer = createLinearBuffer(std::move(mOutputBlock), 0, mEncoderReturnedNbBytes);
        work->worklets.front()->output.buffers.push_back(buffer);
        work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
    } else {
        ALOGV("encoder process_interleaved returned without data to write");
    }

    // cloneAndSend will create clone of work when more than one encoded frame is produced
    while (mOutputBuffers.size() > 1) {
        const OutputBuffer& front = mOutputBuffers.front();
        C2WorkOrdinalStruct ordinal = work->input.ordinal;
        ordinal.frameIndex = front.frameIndex;
        ordinal.timestamp = front.timestampUs;
        cloneAndSend(work->input.ordinal.frameIndex.peeku(), work,
                     FillWork(C2FrameData::FLAG_INCOMPLETE, ordinal, front.buffer));
        mOutputBuffers.pop_front();
    }

    std::shared_ptr<C2Buffer> buffer;
    C2WorkOrdinalStruct ordinal = work->input.ordinal;
    if (mOutputBuffers.size() == 1) {
        const OutputBuffer& front = mOutputBuffers.front();
        ordinal.frameIndex = front.frameIndex;
        ordinal.timestamp = front.timestampUs;
        buffer = front.buffer;
        mOutputBuffers.pop_front();
    }
    // finish the response for the overall transaction.
    // this includes any final frame that the encoder produced during this request
    // this response is required even if no data was encoded.
    FillWork((C2FrameData::flags_t)(eos ? C2FrameData::FLAG_END_OF_STREAM : 0),
             ordinal, buffer)(work);

    mOutputBlock = nullptr;
    if (eos) {
        mSignalledOutputEos = true;
@@ -349,6 +387,8 @@ FLAC__StreamEncoderWriteStatus C2SoftFlacEnc::onEncodedFlacAvailable(
    // write encoded data
    C2WriteView wView = mOutputBlock->map().get();
    uint8_t* outData = wView.data();
    const uint32_t sampleRate = mIntf->getSampleRate();
    const uint64_t outTimeStamp = mProcessedSamples * 1000000ll / sampleRate;
    ALOGV("writing %zu bytes of encoded data on output", bytes);
    // increment mProcessedSamples to maintain audio synchronization during
    // play back
@@ -359,7 +399,12 @@ FLAC__StreamEncoderWriteStatus C2SoftFlacEnc::onEncodedFlacAvailable(
        return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
    }
    memcpy(outData + mEncoderReturnedNbBytes, buffer, bytes);

    std::shared_ptr<C2Buffer> c2Buffer =
        createLinearBuffer(mOutputBlock, mEncoderReturnedNbBytes, bytes);
    mOutputBuffers.push_back({c2Buffer, mAnchorTimeStamp + outTimeStamp, current_frame});
    mEncoderReturnedNbBytes += bytes;

    return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
}

+6 −0
Original line number Diff line number Diff line
@@ -79,6 +79,12 @@ private:
    unsigned mHeaderOffset;
    bool mWroteHeader;
    char mHeader[FLAC_HEADER_SIZE];
    struct OutputBuffer {
        std::shared_ptr<C2Buffer> buffer;
        c2_cntr64_t timestampUs;
        std::uint64_t frameIndex;
    };
    std::list<OutputBuffer> mOutputBuffers;

    C2_DO_NOT_COPY(C2SoftFlacEnc);
};