Loading media/aconfig/codec_fwk.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,16 @@ flag { bug: "325520135" } flag { name: "input_surface_throttle" namespace: "codec_fwk" description: "Bugfix flag for input surface throttle" bug: "342269852" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "large_audio_frame_finish" namespace: "codec_fwk" Loading media/codec2/sfplugin/C2AidlNode.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ void C2AidlNode::onInputBufferDone(c2_cntr64_t index) { return mImpl->onInputBufferDone(index); } void C2AidlNode::onInputBufferEmptied() { return mImpl->onInputBufferEmptied(); } android_dataspace C2AidlNode::getDataspace() { return mImpl->getDataspace(); } Loading media/codec2/sfplugin/C2AidlNode.h +7 −1 Original line number Diff line number Diff line Loading @@ -68,12 +68,18 @@ public: void setFrameSize(uint32_t width, uint32_t height); /** * Clean up work item reference. * Notify that the input buffer reference is no longer needed by the component. * Clean up if necessary. * * \param index input work index */ void onInputBufferDone(c2_cntr64_t index); /** * Notify input buffer is emptied. */ void onInputBufferEmptied(); /** * Returns dataspace information from GraphicBufferSource. */ Loading media/codec2/sfplugin/C2NodeImpl.cpp +61 −12 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <C2Debug.h> #include <C2PlatformSupport.h> #include <android_media_codec.h> #include <android/fdsan.h> #include <media/stagefright/foundation/ColorUtils.h> #include <ui/Fence.h> Loading Loading @@ -373,7 +374,10 @@ status_t C2NodeImpl::submitBuffer( } work->worklets.clear(); work->worklets.emplace_back(new C2Worklet); mBufferIdsInUse.lock()->emplace(work->input.ordinal.frameIndex.peeku(), buffer); { Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker); buffers->mIdsInUse.emplace(work->input.ordinal.frameIndex.peeku(), buffer); } mQueueThread->queue(comp, fenceFd, std::move(work), std::move(fd0), std::move(fd1)); return OK; Loading Loading @@ -405,29 +409,74 @@ void C2NodeImpl::setFrameSize(uint32_t width, uint32_t height) { } void C2NodeImpl::onInputBufferDone(c2_cntr64_t index) { if (mAidlHal) { if (!mAidlBufferSource) { ALOGD("Buffer source not set (index=%llu)", index.peekull()); if (android::media::codec::provider_->input_surface_throttle()) { Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker); auto it = buffers->mIdsInUse.find(index.peeku()); if (it == buffers->mIdsInUse.end()) { ALOGV("Untracked input index %llu (maybe already removed)", index.peekull()); return; } int32_t bufferId = it->second; (void)buffers->mIdsInUse.erase(it); buffers->mAvailableIds.push_back(bufferId); } else { if (!mBufferSource) { ALOGD("Buffer source not set (index=%llu)", index.peekull()); if (!hasBufferSource()) { return; } } int32_t bufferId = 0; { decltype(mBufferIdsInUse)::Locked bufferIds(mBufferIdsInUse); auto it = bufferIds->find(index.peeku()); if (it == bufferIds->end()) { Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker); auto it = buffers->mIdsInUse.find(index.peeku()); if (it == buffers->mIdsInUse.end()) { ALOGV("Untracked input index %llu (maybe already removed)", index.peekull()); return; } bufferId = it->second; (void)bufferIds->erase(it); (void)buffers->mIdsInUse.erase(it); } notifyInputBufferEmptied(bufferId); } } void C2NodeImpl::onInputBufferEmptied() { if (!android::media::codec::provider_->input_surface_throttle()) { ALOGE("onInputBufferEmptied should not be called " "when input_surface_throttle is false"); return; } if (!hasBufferSource()) { return; } int32_t bufferId = 0; { Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker); if (buffers->mAvailableIds.empty()) { ALOGV("The codec is ready to take more input buffers " "but no input buffers are ready yet."); return; } bufferId = buffers->mAvailableIds.front(); buffers->mAvailableIds.pop_front(); } notifyInputBufferEmptied(bufferId); } bool C2NodeImpl::hasBufferSource() { if (mAidlHal) { if (!mAidlBufferSource) { ALOGD("Buffer source not set"); return false; } } else { if (!mBufferSource) { ALOGD("Buffer source not set"); return false; } } return true; } void C2NodeImpl::notifyInputBufferEmptied(int32_t bufferId) { if (mAidlHal) { ::ndk::ScopedFileDescriptor nullFence; (void)mAidlBufferSource->onInputBufferEmptied(bufferId, nullFence); Loading media/codec2/sfplugin/C2NodeImpl.h +20 −2 Original line number Diff line number Diff line Loading @@ -73,12 +73,18 @@ struct C2NodeImpl { void setFrameSize(uint32_t width, uint32_t height); /** * Clean up work item reference. * Notify that the input buffer reference is no longer needed by the component. * Clean up if necessary. * * \param index input work index */ void onInputBufferDone(c2_cntr64_t index); /** * Notify input buffer is emptied. */ void onInputBufferEmptied(); /** * Returns dataspace information from GraphicBufferSource. */ Loading Loading @@ -118,12 +124,24 @@ private: c2_cntr64_t mPrevInputTimestamp; // input timestamp for previous frame c2_cntr64_t mPrevCodecTimestamp; // adjusted (codec) timestamp for previous frame Mutexed<std::map<uint64_t, uint32_t>> mBufferIdsInUse; // Tracks the status of buffers struct BuffersTracker { BuffersTracker() = default; // Keeps track of buffers that are used by the component. Maps timestamp -> ID std::map<uint64_t, uint32_t> mIdsInUse; // Keeps track of the buffer IDs that are available after being released from the component. std::list<uint32_t> mAvailableIds; }; Mutexed<BuffersTracker> mBuffersTracker; class QueueThread; sp<QueueThread> mQueueThread; bool mAidlHal; bool hasBufferSource(); void notifyInputBufferEmptied(int32_t bufferId); }; } // namespace android Loading
media/aconfig/codec_fwk.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,16 @@ flag { bug: "325520135" } flag { name: "input_surface_throttle" namespace: "codec_fwk" description: "Bugfix flag for input surface throttle" bug: "342269852" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "large_audio_frame_finish" namespace: "codec_fwk" Loading
media/codec2/sfplugin/C2AidlNode.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ void C2AidlNode::onInputBufferDone(c2_cntr64_t index) { return mImpl->onInputBufferDone(index); } void C2AidlNode::onInputBufferEmptied() { return mImpl->onInputBufferEmptied(); } android_dataspace C2AidlNode::getDataspace() { return mImpl->getDataspace(); } Loading
media/codec2/sfplugin/C2AidlNode.h +7 −1 Original line number Diff line number Diff line Loading @@ -68,12 +68,18 @@ public: void setFrameSize(uint32_t width, uint32_t height); /** * Clean up work item reference. * Notify that the input buffer reference is no longer needed by the component. * Clean up if necessary. * * \param index input work index */ void onInputBufferDone(c2_cntr64_t index); /** * Notify input buffer is emptied. */ void onInputBufferEmptied(); /** * Returns dataspace information from GraphicBufferSource. */ Loading
media/codec2/sfplugin/C2NodeImpl.cpp +61 −12 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <C2Debug.h> #include <C2PlatformSupport.h> #include <android_media_codec.h> #include <android/fdsan.h> #include <media/stagefright/foundation/ColorUtils.h> #include <ui/Fence.h> Loading Loading @@ -373,7 +374,10 @@ status_t C2NodeImpl::submitBuffer( } work->worklets.clear(); work->worklets.emplace_back(new C2Worklet); mBufferIdsInUse.lock()->emplace(work->input.ordinal.frameIndex.peeku(), buffer); { Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker); buffers->mIdsInUse.emplace(work->input.ordinal.frameIndex.peeku(), buffer); } mQueueThread->queue(comp, fenceFd, std::move(work), std::move(fd0), std::move(fd1)); return OK; Loading Loading @@ -405,29 +409,74 @@ void C2NodeImpl::setFrameSize(uint32_t width, uint32_t height) { } void C2NodeImpl::onInputBufferDone(c2_cntr64_t index) { if (mAidlHal) { if (!mAidlBufferSource) { ALOGD("Buffer source not set (index=%llu)", index.peekull()); if (android::media::codec::provider_->input_surface_throttle()) { Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker); auto it = buffers->mIdsInUse.find(index.peeku()); if (it == buffers->mIdsInUse.end()) { ALOGV("Untracked input index %llu (maybe already removed)", index.peekull()); return; } int32_t bufferId = it->second; (void)buffers->mIdsInUse.erase(it); buffers->mAvailableIds.push_back(bufferId); } else { if (!mBufferSource) { ALOGD("Buffer source not set (index=%llu)", index.peekull()); if (!hasBufferSource()) { return; } } int32_t bufferId = 0; { decltype(mBufferIdsInUse)::Locked bufferIds(mBufferIdsInUse); auto it = bufferIds->find(index.peeku()); if (it == bufferIds->end()) { Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker); auto it = buffers->mIdsInUse.find(index.peeku()); if (it == buffers->mIdsInUse.end()) { ALOGV("Untracked input index %llu (maybe already removed)", index.peekull()); return; } bufferId = it->second; (void)bufferIds->erase(it); (void)buffers->mIdsInUse.erase(it); } notifyInputBufferEmptied(bufferId); } } void C2NodeImpl::onInputBufferEmptied() { if (!android::media::codec::provider_->input_surface_throttle()) { ALOGE("onInputBufferEmptied should not be called " "when input_surface_throttle is false"); return; } if (!hasBufferSource()) { return; } int32_t bufferId = 0; { Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker); if (buffers->mAvailableIds.empty()) { ALOGV("The codec is ready to take more input buffers " "but no input buffers are ready yet."); return; } bufferId = buffers->mAvailableIds.front(); buffers->mAvailableIds.pop_front(); } notifyInputBufferEmptied(bufferId); } bool C2NodeImpl::hasBufferSource() { if (mAidlHal) { if (!mAidlBufferSource) { ALOGD("Buffer source not set"); return false; } } else { if (!mBufferSource) { ALOGD("Buffer source not set"); return false; } } return true; } void C2NodeImpl::notifyInputBufferEmptied(int32_t bufferId) { if (mAidlHal) { ::ndk::ScopedFileDescriptor nullFence; (void)mAidlBufferSource->onInputBufferEmptied(bufferId, nullFence); Loading
media/codec2/sfplugin/C2NodeImpl.h +20 −2 Original line number Diff line number Diff line Loading @@ -73,12 +73,18 @@ struct C2NodeImpl { void setFrameSize(uint32_t width, uint32_t height); /** * Clean up work item reference. * Notify that the input buffer reference is no longer needed by the component. * Clean up if necessary. * * \param index input work index */ void onInputBufferDone(c2_cntr64_t index); /** * Notify input buffer is emptied. */ void onInputBufferEmptied(); /** * Returns dataspace information from GraphicBufferSource. */ Loading Loading @@ -118,12 +124,24 @@ private: c2_cntr64_t mPrevInputTimestamp; // input timestamp for previous frame c2_cntr64_t mPrevCodecTimestamp; // adjusted (codec) timestamp for previous frame Mutexed<std::map<uint64_t, uint32_t>> mBufferIdsInUse; // Tracks the status of buffers struct BuffersTracker { BuffersTracker() = default; // Keeps track of buffers that are used by the component. Maps timestamp -> ID std::map<uint64_t, uint32_t> mIdsInUse; // Keeps track of the buffer IDs that are available after being released from the component. std::list<uint32_t> mAvailableIds; }; Mutexed<BuffersTracker> mBuffersTracker; class QueueThread; sp<QueueThread> mQueueThread; bool mAidlHal; bool hasBufferSource(); void notifyInputBufferEmptied(int32_t bufferId); }; } // namespace android