Loading media/codec2/hidl/client/client.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -1502,6 +1502,7 @@ c2_status_t Codec2Client::Component::setOutputSurface( igbp = new B2HGraphicBufferProducer2(surface); } std::scoped_lock lock(mOutputMutex); std::shared_ptr<SurfaceSyncObj> syncObj; if (!surface) { Loading Loading @@ -1586,6 +1587,24 @@ void Codec2Client::Component::setOutputSurfaceMaxDequeueCount( mOutputBufferQueue->updateMaxDequeueBufferCount(maxDequeueCount); } void Codec2Client::Component::stopUsingOutputSurface( C2BlockPool::local_id_t blockPoolId) { std::scoped_lock lock(mOutputMutex); mOutputBufferQueue->stop(); Return<Status> transStatus = mBase1_0->setOutputSurface( static_cast<uint64_t>(blockPoolId), nullptr); if (!transStatus.isOk()) { LOG(ERROR) << "setOutputSurface(stopUsingOutputSurface) -- transaction failed."; } else { c2_status_t status = static_cast<c2_status_t>(static_cast<Status>(transStatus)); if (status != C2_OK) { LOG(DEBUG) << "setOutputSurface(stopUsingOutputSurface) -- call failed: " << status << "."; } } } c2_status_t Codec2Client::Component::connectToInputSurface( const std::shared_ptr<InputSurface>& inputSurface, std::shared_ptr<InputSurfaceConnection>* connection) { Loading media/codec2/hidl/client/include/codec2/hidl/client.h +9 −0 Original line number Diff line number Diff line Loading @@ -411,6 +411,10 @@ struct Codec2Client::Component : public Codec2Client::Configurable { // Set max dequeue count for output surface. void setOutputSurfaceMaxDequeueCount(int maxDequeueCount); // Stop using the current output surface. void stopUsingOutputSurface( C2BlockPool::local_id_t blockPoolId); // Connect to a given InputSurface. c2_status_t connectToInputSurface( const std::shared_ptr<InputSurface>& inputSurface, Loading Loading @@ -441,6 +445,11 @@ protected: struct OutputBufferQueue; std::unique_ptr<OutputBufferQueue> mOutputBufferQueue; // (b/202903117) Sometimes MediaCodec::setSurface races between normal // setSurface and setSurface with ReleaseSurface due to timing issues. // In order to prevent the race condition mutex is added. std::mutex mOutputMutex; static c2_status_t setDeathListener( const std::shared_ptr<Component>& component, const std::shared_ptr<Listener>& listener); Loading media/codec2/hidl/client/include/codec2/hidl/output.h +5 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,10 @@ struct OutputBufferQueue { int maxDequeueBufferCount, std::shared_ptr<V1_2::SurfaceSyncObj> *syncObj); // Stop using the current output surface. Pending buffer opeations will not // perform anymore. void stop(); // Render a graphic block to current surface. status_t outputBuffer( const C2ConstGraphicBlock& block, Loading Loading @@ -81,6 +85,7 @@ private: sp<GraphicBuffer> mBuffers[BufferQueueDefs::NUM_BUFFER_SLOTS]; // find a better way std::weak_ptr<_C2BlockPoolData> mPoolDatas[BufferQueueDefs::NUM_BUFFER_SLOTS]; std::shared_ptr<C2SurfaceSyncMemory> mSyncMem; bool mStopped; bool registerBuffer(const C2ConstGraphicBlock& block); }; Loading media/codec2/hidl/client/output.cpp +24 −4 Original line number Diff line number Diff line Loading @@ -169,7 +169,7 @@ bool getBufferQueueAssignment(const C2ConstGraphicBlock& block, } // unnamed namespace OutputBufferQueue::OutputBufferQueue() : mGeneration{0}, mBqId{0} { : mGeneration{0}, mBqId{0}, mStopped{false} { } OutputBufferQueue::~OutputBufferQueue() { Loading Loading @@ -219,6 +219,8 @@ bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp, poolDatas[BufferQueueDefs::NUM_BUFFER_SLOTS]; { std::scoped_lock<std::mutex> l(mMutex); bool stopped = mStopped; mStopped = false; if (generation == mGeneration) { // case of old BlockPool destruction C2SyncVariables *var = mSyncMem ? mSyncMem->mem() : nullptr; Loading Loading @@ -258,7 +260,7 @@ bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp, return false; } for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; ++i) { if (mBqId == 0 || !mBuffers[i]) { if (mBqId == 0 || !mBuffers[i] || stopped) { continue; } std::shared_ptr<_C2BlockPoolData> data = mPoolDatas[i].lock(); Loading Loading @@ -317,6 +319,12 @@ bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp, return true; } void OutputBufferQueue::stop() { std::scoped_lock<std::mutex> l(mMutex); mStopped = true; mOwner.reset(); // destructor of the block will not triger IGBP::cancel() } bool OutputBufferQueue::registerBuffer(const C2ConstGraphicBlock& block) { std::shared_ptr<_C2BlockPoolData> data = _C2BlockFactory::GetGraphicBlockPoolData(block); Loading @@ -325,7 +333,7 @@ bool OutputBufferQueue::registerBuffer(const C2ConstGraphicBlock& block) { } std::scoped_lock<std::mutex> l(mMutex); if (!mIgbp) { if (!mIgbp || mStopped) { return false; } Loading Loading @@ -371,11 +379,17 @@ status_t OutputBufferQueue::outputBuffer( std::shared_ptr<C2SurfaceSyncMemory> syncMem; mMutex.lock(); bool stopped = mStopped; sp<IGraphicBufferProducer> outputIgbp = mIgbp; uint32_t outputGeneration = mGeneration; syncMem = mSyncMem; mMutex.unlock(); if (stopped) { LOG(INFO) << "outputBuffer -- already stopped."; return DEAD_OBJECT; } status_t status = attachToBufferQueue( block, outputIgbp, outputGeneration, &bqSlot, syncMem); Loading Loading @@ -408,12 +422,18 @@ status_t OutputBufferQueue::outputBuffer( std::shared_ptr<C2SurfaceSyncMemory> syncMem; mMutex.lock(); bool stopped = mStopped; sp<IGraphicBufferProducer> outputIgbp = mIgbp; uint32_t outputGeneration = mGeneration; uint64_t outputBqId = mBqId; syncMem = mSyncMem; mMutex.unlock(); if (stopped) { LOG(INFO) << "outputBuffer -- already stopped."; return DEAD_OBJECT; } if (!outputIgbp) { LOG(VERBOSE) << "outputBuffer -- output surface is null."; return NO_INIT; Loading Loading @@ -467,7 +487,7 @@ void OutputBufferQueue::updateMaxDequeueBufferCount(int maxDequeueBufferCount) { mMutex.lock(); mMaxDequeueBufferCount = maxDequeueBufferCount; auto syncVar = mSyncMem ? mSyncMem->mem() : nullptr; if (syncVar) { if (syncVar && !mStopped) { syncVar->lock(); syncVar->updateMaxDequeueCountLocked(maxDequeueBufferCount); syncVar->unlock(); Loading media/codec2/sfplugin/CCodecBufferChannel.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -1570,6 +1570,14 @@ void CCodecBufferChannel::reset() { Mutexed<Output>::Locked output(mOutput); output->buffers.reset(); } if (mOutputSurface.lock()->surface) { C2BlockPool::local_id_t outputPoolId; { Mutexed<BlockPools>::Locked pools(mBlockPools); outputPoolId = pools->outputPoolId; } mComponent->stopUsingOutputSurface(outputPoolId); } } void CCodecBufferChannel::release() { Loading Loading
media/codec2/hidl/client/client.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -1502,6 +1502,7 @@ c2_status_t Codec2Client::Component::setOutputSurface( igbp = new B2HGraphicBufferProducer2(surface); } std::scoped_lock lock(mOutputMutex); std::shared_ptr<SurfaceSyncObj> syncObj; if (!surface) { Loading Loading @@ -1586,6 +1587,24 @@ void Codec2Client::Component::setOutputSurfaceMaxDequeueCount( mOutputBufferQueue->updateMaxDequeueBufferCount(maxDequeueCount); } void Codec2Client::Component::stopUsingOutputSurface( C2BlockPool::local_id_t blockPoolId) { std::scoped_lock lock(mOutputMutex); mOutputBufferQueue->stop(); Return<Status> transStatus = mBase1_0->setOutputSurface( static_cast<uint64_t>(blockPoolId), nullptr); if (!transStatus.isOk()) { LOG(ERROR) << "setOutputSurface(stopUsingOutputSurface) -- transaction failed."; } else { c2_status_t status = static_cast<c2_status_t>(static_cast<Status>(transStatus)); if (status != C2_OK) { LOG(DEBUG) << "setOutputSurface(stopUsingOutputSurface) -- call failed: " << status << "."; } } } c2_status_t Codec2Client::Component::connectToInputSurface( const std::shared_ptr<InputSurface>& inputSurface, std::shared_ptr<InputSurfaceConnection>* connection) { Loading
media/codec2/hidl/client/include/codec2/hidl/client.h +9 −0 Original line number Diff line number Diff line Loading @@ -411,6 +411,10 @@ struct Codec2Client::Component : public Codec2Client::Configurable { // Set max dequeue count for output surface. void setOutputSurfaceMaxDequeueCount(int maxDequeueCount); // Stop using the current output surface. void stopUsingOutputSurface( C2BlockPool::local_id_t blockPoolId); // Connect to a given InputSurface. c2_status_t connectToInputSurface( const std::shared_ptr<InputSurface>& inputSurface, Loading Loading @@ -441,6 +445,11 @@ protected: struct OutputBufferQueue; std::unique_ptr<OutputBufferQueue> mOutputBufferQueue; // (b/202903117) Sometimes MediaCodec::setSurface races between normal // setSurface and setSurface with ReleaseSurface due to timing issues. // In order to prevent the race condition mutex is added. std::mutex mOutputMutex; static c2_status_t setDeathListener( const std::shared_ptr<Component>& component, const std::shared_ptr<Listener>& listener); Loading
media/codec2/hidl/client/include/codec2/hidl/output.h +5 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,10 @@ struct OutputBufferQueue { int maxDequeueBufferCount, std::shared_ptr<V1_2::SurfaceSyncObj> *syncObj); // Stop using the current output surface. Pending buffer opeations will not // perform anymore. void stop(); // Render a graphic block to current surface. status_t outputBuffer( const C2ConstGraphicBlock& block, Loading Loading @@ -81,6 +85,7 @@ private: sp<GraphicBuffer> mBuffers[BufferQueueDefs::NUM_BUFFER_SLOTS]; // find a better way std::weak_ptr<_C2BlockPoolData> mPoolDatas[BufferQueueDefs::NUM_BUFFER_SLOTS]; std::shared_ptr<C2SurfaceSyncMemory> mSyncMem; bool mStopped; bool registerBuffer(const C2ConstGraphicBlock& block); }; Loading
media/codec2/hidl/client/output.cpp +24 −4 Original line number Diff line number Diff line Loading @@ -169,7 +169,7 @@ bool getBufferQueueAssignment(const C2ConstGraphicBlock& block, } // unnamed namespace OutputBufferQueue::OutputBufferQueue() : mGeneration{0}, mBqId{0} { : mGeneration{0}, mBqId{0}, mStopped{false} { } OutputBufferQueue::~OutputBufferQueue() { Loading Loading @@ -219,6 +219,8 @@ bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp, poolDatas[BufferQueueDefs::NUM_BUFFER_SLOTS]; { std::scoped_lock<std::mutex> l(mMutex); bool stopped = mStopped; mStopped = false; if (generation == mGeneration) { // case of old BlockPool destruction C2SyncVariables *var = mSyncMem ? mSyncMem->mem() : nullptr; Loading Loading @@ -258,7 +260,7 @@ bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp, return false; } for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; ++i) { if (mBqId == 0 || !mBuffers[i]) { if (mBqId == 0 || !mBuffers[i] || stopped) { continue; } std::shared_ptr<_C2BlockPoolData> data = mPoolDatas[i].lock(); Loading Loading @@ -317,6 +319,12 @@ bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp, return true; } void OutputBufferQueue::stop() { std::scoped_lock<std::mutex> l(mMutex); mStopped = true; mOwner.reset(); // destructor of the block will not triger IGBP::cancel() } bool OutputBufferQueue::registerBuffer(const C2ConstGraphicBlock& block) { std::shared_ptr<_C2BlockPoolData> data = _C2BlockFactory::GetGraphicBlockPoolData(block); Loading @@ -325,7 +333,7 @@ bool OutputBufferQueue::registerBuffer(const C2ConstGraphicBlock& block) { } std::scoped_lock<std::mutex> l(mMutex); if (!mIgbp) { if (!mIgbp || mStopped) { return false; } Loading Loading @@ -371,11 +379,17 @@ status_t OutputBufferQueue::outputBuffer( std::shared_ptr<C2SurfaceSyncMemory> syncMem; mMutex.lock(); bool stopped = mStopped; sp<IGraphicBufferProducer> outputIgbp = mIgbp; uint32_t outputGeneration = mGeneration; syncMem = mSyncMem; mMutex.unlock(); if (stopped) { LOG(INFO) << "outputBuffer -- already stopped."; return DEAD_OBJECT; } status_t status = attachToBufferQueue( block, outputIgbp, outputGeneration, &bqSlot, syncMem); Loading Loading @@ -408,12 +422,18 @@ status_t OutputBufferQueue::outputBuffer( std::shared_ptr<C2SurfaceSyncMemory> syncMem; mMutex.lock(); bool stopped = mStopped; sp<IGraphicBufferProducer> outputIgbp = mIgbp; uint32_t outputGeneration = mGeneration; uint64_t outputBqId = mBqId; syncMem = mSyncMem; mMutex.unlock(); if (stopped) { LOG(INFO) << "outputBuffer -- already stopped."; return DEAD_OBJECT; } if (!outputIgbp) { LOG(VERBOSE) << "outputBuffer -- output surface is null."; return NO_INIT; Loading Loading @@ -467,7 +487,7 @@ void OutputBufferQueue::updateMaxDequeueBufferCount(int maxDequeueBufferCount) { mMutex.lock(); mMaxDequeueBufferCount = maxDequeueBufferCount; auto syncVar = mSyncMem ? mSyncMem->mem() : nullptr; if (syncVar) { if (syncVar && !mStopped) { syncVar->lock(); syncVar->updateMaxDequeueCountLocked(maxDequeueBufferCount); syncVar->unlock(); Loading
media/codec2/sfplugin/CCodecBufferChannel.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -1570,6 +1570,14 @@ void CCodecBufferChannel::reset() { Mutexed<Output>::Locked output(mOutput); output->buffers.reset(); } if (mOutputSurface.lock()->surface) { C2BlockPool::local_id_t outputPoolId; { Mutexed<BlockPools>::Locked pools(mBlockPools); outputPoolId = pools->outputPoolId; } mComponent->stopUsingOutputSurface(outputPoolId); } } void CCodecBufferChannel::release() { Loading