Loading media/codec2/components/flac/C2SoftFlacEnc.cpp +60 −15 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading @@ -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; } Loading media/codec2/components/flac/C2SoftFlacEnc.h +6 −0 Original line number Diff line number Diff line Loading @@ -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); }; Loading Loading
media/codec2/components/flac/C2SoftFlacEnc.cpp +60 −15 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading @@ -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; } Loading
media/codec2/components/flac/C2SoftFlacEnc.h +6 −0 Original line number Diff line number Diff line Loading @@ -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); }; Loading