Loading media/codec2/sfplugin/CCodec.cpp +19 −22 Original line number Diff line number Diff line Loading @@ -1868,18 +1868,14 @@ void CCodec::initiateStop() { } state->set(STOPPING); } { Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig); const std::unique_ptr<Config> &config = *configLocked; if (config->mPushBlankBuffersOnStop) { mChannel->pushBlankBufferToOutputSurface(); } } mChannel->reset(); (new AMessage(kWhatStop, this))->post(); bool pushBlankBuffer = mConfig.lock().get()->mPushBlankBuffersOnStop; sp<AMessage> stopMessage(new AMessage(kWhatStop, this)); stopMessage->setInt32("pushBlankBuffer", pushBlankBuffer); stopMessage->post(); } void CCodec::stop() { void CCodec::stop(bool pushBlankBuffer) { std::shared_ptr<Codec2Client::Component> comp; { Mutexed<State>::Locked state(mState); Loading @@ -1898,7 +1894,7 @@ void CCodec::stop() { comp = state->comp; } status_t err = comp->stop(); mChannel->stopUseOutputSurface(); mChannel->stopUseOutputSurface(pushBlankBuffer); if (err != C2_OK) { // TODO: convert err into status_t mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); Loading Loading @@ -1963,21 +1959,16 @@ void CCodec::initiateRelease(bool sendCallback /* = true */) { config->mInputSurfaceDataspace = HAL_DATASPACE_UNKNOWN; } } { Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig); const std::unique_ptr<Config> &config = *configLocked; if (config->mPushBlankBuffersOnStop) { mChannel->pushBlankBufferToOutputSurface(); } } mChannel->reset(); bool pushBlankBuffer = mConfig.lock().get()->mPushBlankBuffersOnStop; // thiz holds strong ref to this while the thread is running. sp<CCodec> thiz(this); std::thread([thiz, sendCallback] { thiz->release(sendCallback); }).detach(); std::thread([thiz, sendCallback, pushBlankBuffer] { thiz->release(sendCallback, pushBlankBuffer); }).detach(); } void CCodec::release(bool sendCallback) { void CCodec::release(bool sendCallback, bool pushBlankBuffer) { std::shared_ptr<Codec2Client::Component> comp; { Mutexed<State>::Locked state(mState); Loading @@ -1992,7 +1983,7 @@ void CCodec::release(bool sendCallback) { comp = state->comp; } comp->release(); mChannel->stopUseOutputSurface(); mChannel->stopUseOutputSurface(pushBlankBuffer); { Mutexed<State>::Locked state(mState); Loading @@ -2006,6 +1997,7 @@ void CCodec::release(bool sendCallback) { } status_t CCodec::setSurface(const sp<Surface> &surface) { bool pushBlankBuffer = false; { Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig); const std::unique_ptr<Config> &config = *configLocked; Loading @@ -2031,8 +2023,9 @@ status_t CCodec::setSurface(const sp<Surface> &surface) { return err; } } pushBlankBuffer = config->mPushBlankBuffersOnStop; } return mChannel->setSurface(surface); return mChannel->setSurface(surface, pushBlankBuffer); } void CCodec::signalFlush() { Loading Loading @@ -2331,7 +2324,11 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatStop: { // C2Component::stop() should return within 500ms. setDeadline(now, 1500ms, "stop"); stop(); int32_t pushBlankBuffer; if (!msg->findInt32("pushBlankBuffer", &pushBlankBuffer)) { pushBlankBuffer = 0; } stop(static_cast<bool>(pushBlankBuffer)); break; } case kWhatFlush: { Loading media/codec2/sfplugin/CCodecBufferChannel.cpp +27 −13 Original line number Diff line number Diff line Loading @@ -1581,14 +1581,22 @@ void CCodecBufferChannel::stop() { mFirstValidFrameIndex = mFrameIndex.load(std::memory_order_relaxed); } void CCodecBufferChannel::stopUseOutputSurface() { if (mOutputSurface.lock()->surface) { void CCodecBufferChannel::stopUseOutputSurface(bool pushBlankBuffer) { sp<Surface> surface = mOutputSurface.lock()->surface; if (surface) { C2BlockPool::local_id_t outputPoolId; { Mutexed<BlockPools>::Locked pools(mBlockPools); outputPoolId = pools->outputPoolId; } if (mComponent) mComponent->stopUsingOutputSurface(outputPoolId); if (pushBlankBuffer) { sp<ANativeWindow> anw = static_cast<ANativeWindow *>(surface.get()); if (anw) { pushBlankBuffersToNativeWindow(anw.get()); } } } } Loading Loading @@ -2106,14 +2114,20 @@ void CCodecBufferChannel::sendOutputBuffers() { } } status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) { status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface, bool pushBlankBuffer) { static std::atomic_uint32_t surfaceGeneration{0}; uint32_t generation = (getpid() << 10) | ((surfaceGeneration.fetch_add(1, std::memory_order_relaxed) + 1) & ((1 << 10) - 1)); sp<IGraphicBufferProducer> producer; int maxDequeueCount = mOutputSurface.lock()->maxDequeueBuffers; int maxDequeueCount; sp<Surface> oldSurface; { Mutexed<OutputSurface>::Locked outputSurface(mOutputSurface); maxDequeueCount = outputSurface->maxDequeueBuffers; oldSurface = outputSurface->surface; } if (newSurface) { newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); newSurface->setDequeueTimeout(kDequeueTimeoutNs); Loading Loading @@ -2150,6 +2164,15 @@ status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) { output->generation = generation; } if (oldSurface && pushBlankBuffer) { // When ReleaseSurface was set from MediaCodec, // pushing a blank buffer at the end might be necessary. sp<ANativeWindow> anw = static_cast<ANativeWindow *>(oldSurface.get()); if (anw) { pushBlankBuffersToNativeWindow(anw.get()); } } return OK; } Loading Loading @@ -2239,13 +2262,4 @@ status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) { } } status_t CCodecBufferChannel::pushBlankBufferToOutputSurface() { Mutexed<OutputSurface>::Locked output(mOutputSurface); sp<ANativeWindow> nativeWindow = static_cast<ANativeWindow *>(output->surface.get()); if (nativeWindow == nullptr) { return INVALID_OPERATION; } return pushBlankBuffersToNativeWindow(nativeWindow.get()); } } // namespace android media/codec2/sfplugin/CCodecBufferChannel.h +4 −7 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ public: /** * Set output graphic surface for rendering. */ status_t setSurface(const sp<Surface> &surface); status_t setSurface(const sp<Surface> &surface, bool pushBlankBuffer); /** * Set GraphicBufferSource object from which the component extracts input Loading Loading @@ -151,8 +151,10 @@ public: /** * Stop using buffers of the current output surface for other Codec * instances to use the surface safely. * * \param pushBlankBuffer[in] push a blank buffer at the end if true */ void stopUseOutputSurface(); void stopUseOutputSurface(bool pushBlankBuffer); /** * Stop queueing buffers to the component. This object should never queue Loading Loading @@ -201,11 +203,6 @@ public: void setMetaMode(MetaMode mode); /** * Push a blank buffer to the configured native output surface. */ status_t pushBlankBufferToOutputSurface(); private: class QueueGuard; Loading media/codec2/sfplugin/include/media/stagefright/CCodec.h +2 −2 Original line number Diff line number Diff line Loading @@ -109,9 +109,9 @@ private: void allocate(const sp<MediaCodecInfo> &codecInfo); void configure(const sp<AMessage> &msg); void start(); void stop(); void stop(bool pushBlankBuffer); void flush(); void release(bool sendCallback); void release(bool sendCallback, bool pushBlankBuffer); /** * Creates an input surface for the current device configuration compatible with CCodec. Loading media/libstagefright/SurfaceUtils.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,11 @@ status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull * static_cast<Surface*>(nativeWindow)->getIGraphicBufferProducer()->allowAllocation(true); // In nonblocking mode(timetout = 0), native_window_dequeue_buffer_and_wait() // can fail with timeout. Changing to blocking mode will ensure that dequeue // does not timeout. static_cast<Surface*>(nativeWindow)->getIGraphicBufferProducer()->setDequeueTimeout(-1); err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); if (err != NO_ERROR) { Loading Loading
media/codec2/sfplugin/CCodec.cpp +19 −22 Original line number Diff line number Diff line Loading @@ -1868,18 +1868,14 @@ void CCodec::initiateStop() { } state->set(STOPPING); } { Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig); const std::unique_ptr<Config> &config = *configLocked; if (config->mPushBlankBuffersOnStop) { mChannel->pushBlankBufferToOutputSurface(); } } mChannel->reset(); (new AMessage(kWhatStop, this))->post(); bool pushBlankBuffer = mConfig.lock().get()->mPushBlankBuffersOnStop; sp<AMessage> stopMessage(new AMessage(kWhatStop, this)); stopMessage->setInt32("pushBlankBuffer", pushBlankBuffer); stopMessage->post(); } void CCodec::stop() { void CCodec::stop(bool pushBlankBuffer) { std::shared_ptr<Codec2Client::Component> comp; { Mutexed<State>::Locked state(mState); Loading @@ -1898,7 +1894,7 @@ void CCodec::stop() { comp = state->comp; } status_t err = comp->stop(); mChannel->stopUseOutputSurface(); mChannel->stopUseOutputSurface(pushBlankBuffer); if (err != C2_OK) { // TODO: convert err into status_t mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); Loading Loading @@ -1963,21 +1959,16 @@ void CCodec::initiateRelease(bool sendCallback /* = true */) { config->mInputSurfaceDataspace = HAL_DATASPACE_UNKNOWN; } } { Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig); const std::unique_ptr<Config> &config = *configLocked; if (config->mPushBlankBuffersOnStop) { mChannel->pushBlankBufferToOutputSurface(); } } mChannel->reset(); bool pushBlankBuffer = mConfig.lock().get()->mPushBlankBuffersOnStop; // thiz holds strong ref to this while the thread is running. sp<CCodec> thiz(this); std::thread([thiz, sendCallback] { thiz->release(sendCallback); }).detach(); std::thread([thiz, sendCallback, pushBlankBuffer] { thiz->release(sendCallback, pushBlankBuffer); }).detach(); } void CCodec::release(bool sendCallback) { void CCodec::release(bool sendCallback, bool pushBlankBuffer) { std::shared_ptr<Codec2Client::Component> comp; { Mutexed<State>::Locked state(mState); Loading @@ -1992,7 +1983,7 @@ void CCodec::release(bool sendCallback) { comp = state->comp; } comp->release(); mChannel->stopUseOutputSurface(); mChannel->stopUseOutputSurface(pushBlankBuffer); { Mutexed<State>::Locked state(mState); Loading @@ -2006,6 +1997,7 @@ void CCodec::release(bool sendCallback) { } status_t CCodec::setSurface(const sp<Surface> &surface) { bool pushBlankBuffer = false; { Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig); const std::unique_ptr<Config> &config = *configLocked; Loading @@ -2031,8 +2023,9 @@ status_t CCodec::setSurface(const sp<Surface> &surface) { return err; } } pushBlankBuffer = config->mPushBlankBuffersOnStop; } return mChannel->setSurface(surface); return mChannel->setSurface(surface, pushBlankBuffer); } void CCodec::signalFlush() { Loading Loading @@ -2331,7 +2324,11 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatStop: { // C2Component::stop() should return within 500ms. setDeadline(now, 1500ms, "stop"); stop(); int32_t pushBlankBuffer; if (!msg->findInt32("pushBlankBuffer", &pushBlankBuffer)) { pushBlankBuffer = 0; } stop(static_cast<bool>(pushBlankBuffer)); break; } case kWhatFlush: { Loading
media/codec2/sfplugin/CCodecBufferChannel.cpp +27 −13 Original line number Diff line number Diff line Loading @@ -1581,14 +1581,22 @@ void CCodecBufferChannel::stop() { mFirstValidFrameIndex = mFrameIndex.load(std::memory_order_relaxed); } void CCodecBufferChannel::stopUseOutputSurface() { if (mOutputSurface.lock()->surface) { void CCodecBufferChannel::stopUseOutputSurface(bool pushBlankBuffer) { sp<Surface> surface = mOutputSurface.lock()->surface; if (surface) { C2BlockPool::local_id_t outputPoolId; { Mutexed<BlockPools>::Locked pools(mBlockPools); outputPoolId = pools->outputPoolId; } if (mComponent) mComponent->stopUsingOutputSurface(outputPoolId); if (pushBlankBuffer) { sp<ANativeWindow> anw = static_cast<ANativeWindow *>(surface.get()); if (anw) { pushBlankBuffersToNativeWindow(anw.get()); } } } } Loading Loading @@ -2106,14 +2114,20 @@ void CCodecBufferChannel::sendOutputBuffers() { } } status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) { status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface, bool pushBlankBuffer) { static std::atomic_uint32_t surfaceGeneration{0}; uint32_t generation = (getpid() << 10) | ((surfaceGeneration.fetch_add(1, std::memory_order_relaxed) + 1) & ((1 << 10) - 1)); sp<IGraphicBufferProducer> producer; int maxDequeueCount = mOutputSurface.lock()->maxDequeueBuffers; int maxDequeueCount; sp<Surface> oldSurface; { Mutexed<OutputSurface>::Locked outputSurface(mOutputSurface); maxDequeueCount = outputSurface->maxDequeueBuffers; oldSurface = outputSurface->surface; } if (newSurface) { newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); newSurface->setDequeueTimeout(kDequeueTimeoutNs); Loading Loading @@ -2150,6 +2164,15 @@ status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) { output->generation = generation; } if (oldSurface && pushBlankBuffer) { // When ReleaseSurface was set from MediaCodec, // pushing a blank buffer at the end might be necessary. sp<ANativeWindow> anw = static_cast<ANativeWindow *>(oldSurface.get()); if (anw) { pushBlankBuffersToNativeWindow(anw.get()); } } return OK; } Loading Loading @@ -2239,13 +2262,4 @@ status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) { } } status_t CCodecBufferChannel::pushBlankBufferToOutputSurface() { Mutexed<OutputSurface>::Locked output(mOutputSurface); sp<ANativeWindow> nativeWindow = static_cast<ANativeWindow *>(output->surface.get()); if (nativeWindow == nullptr) { return INVALID_OPERATION; } return pushBlankBuffersToNativeWindow(nativeWindow.get()); } } // namespace android
media/codec2/sfplugin/CCodecBufferChannel.h +4 −7 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ public: /** * Set output graphic surface for rendering. */ status_t setSurface(const sp<Surface> &surface); status_t setSurface(const sp<Surface> &surface, bool pushBlankBuffer); /** * Set GraphicBufferSource object from which the component extracts input Loading Loading @@ -151,8 +151,10 @@ public: /** * Stop using buffers of the current output surface for other Codec * instances to use the surface safely. * * \param pushBlankBuffer[in] push a blank buffer at the end if true */ void stopUseOutputSurface(); void stopUseOutputSurface(bool pushBlankBuffer); /** * Stop queueing buffers to the component. This object should never queue Loading Loading @@ -201,11 +203,6 @@ public: void setMetaMode(MetaMode mode); /** * Push a blank buffer to the configured native output surface. */ status_t pushBlankBufferToOutputSurface(); private: class QueueGuard; Loading
media/codec2/sfplugin/include/media/stagefright/CCodec.h +2 −2 Original line number Diff line number Diff line Loading @@ -109,9 +109,9 @@ private: void allocate(const sp<MediaCodecInfo> &codecInfo); void configure(const sp<AMessage> &msg); void start(); void stop(); void stop(bool pushBlankBuffer); void flush(); void release(bool sendCallback); void release(bool sendCallback, bool pushBlankBuffer); /** * Creates an input surface for the current device configuration compatible with CCodec. Loading
media/libstagefright/SurfaceUtils.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,11 @@ status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull * static_cast<Surface*>(nativeWindow)->getIGraphicBufferProducer()->allowAllocation(true); // In nonblocking mode(timetout = 0), native_window_dequeue_buffer_and_wait() // can fail with timeout. Changing to blocking mode will ensure that dequeue // does not timeout. static_cast<Surface*>(nativeWindow)->getIGraphicBufferProducer()->setDequeueTimeout(-1); err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); if (err != NO_ERROR) { Loading