From 520e1d07a7870f4256434d33e3ef9a21e6796d41 Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Wed, 10 Apr 2019 04:14:52 -0700 Subject: RESTRICT AUTOMERGE Gate input buffers from input surface Test: Record videos with Camera app Bug: 123848562 Change-Id: I50e7d945a62d59d6df774051e557238f1219b32d --- media/sfplugin/C2OMXNode.cpp | 12 +++++++-- media/sfplugin/C2OMXNode.h | 10 +++++++- media/sfplugin/CCodec.cpp | 9 ++++--- media/sfplugin/CCodecBufferChannel.cpp | 46 +++++++++++++++++++++++++++++++++- media/sfplugin/CCodecBufferChannel.h | 15 +++++++++++ media/sfplugin/InputSurfaceWrapper.h | 20 ++++++++++++++- 6 files changed, 104 insertions(+), 8 deletions(-) diff --git a/media/sfplugin/C2OMXNode.cpp b/media/sfplugin/C2OMXNode.cpp index 73cbbc6..92b86b6 100644 --- a/media/sfplugin/C2OMXNode.cpp +++ b/media/sfplugin/C2OMXNode.cpp @@ -49,8 +49,10 @@ public: } // namespace -C2OMXNode::C2OMXNode(const std::shared_ptr &comp) - : mComp(comp), mFrameIndex(0), mWidth(0), mHeight(0), +C2OMXNode::C2OMXNode(const std::shared_ptr &comp, + const std::shared_ptr &inputGater) + : mComp(comp), mInputGater(inputGater), + mFrameIndex(0), mWidth(0), mHeight(0), mAdjustTimestampGapUs(0), mFirstInputFrame(true) { // TODO: read from intf() if (!strncmp(comp->getName().c_str(), "c2.android.", 11)) { @@ -212,6 +214,7 @@ status_t C2OMXNode::emptyBuffer( sp fence = new Fence(fenceFd); fence->waitForever(LOG_TAG); } + std::shared_ptr comp = mComp.lock(); if (!comp) { return NO_INIT; @@ -287,6 +290,11 @@ status_t C2OMXNode::emptyBuffer( std::list> items; items.push_back(std::move(work)); + std::shared_ptr inputGater = mInputGater.lock(); + if (!inputGater || !inputGater->canQueue()) { + return OK; + } + c2_status_t err = comp->queue(&items); if (err != C2_OK) { return UNKNOWN_ERROR; diff --git a/media/sfplugin/C2OMXNode.h b/media/sfplugin/C2OMXNode.h index b5a815e..a81a993 100644 --- a/media/sfplugin/C2OMXNode.h +++ b/media/sfplugin/C2OMXNode.h @@ -24,6 +24,8 @@ #include #include +#include "InputSurfaceWrapper.h" + namespace android { /** @@ -33,7 +35,12 @@ namespace android { * to work in any other usage than IGraphicBufferSource. */ struct C2OMXNode : public BnOMXNode { - explicit C2OMXNode(const std::shared_ptr &comp); + + using InputGater = InputSurfaceWrapper::InputGater; + + explicit C2OMXNode( + const std::shared_ptr &comp, + const std::shared_ptr &inputGater); ~C2OMXNode() override = default; // IOMXNode @@ -80,6 +87,7 @@ struct C2OMXNode : public BnOMXNode { private: std::weak_ptr mComp; + std::weak_ptr mInputGater; sp mBufferSource; std::shared_ptr mAllocator; std::atomic_uint64_t mFrameIndex; diff --git a/media/sfplugin/CCodec.cpp b/media/sfplugin/CCodec.cpp index 20c3de3..e370edd 100644 --- a/media/sfplugin/CCodec.cpp +++ b/media/sfplugin/CCodec.cpp @@ -139,7 +139,8 @@ public: ~C2InputSurfaceWrapper() override = default; - status_t connect(const std::shared_ptr &comp) override { + status_t connect(const std::shared_ptr &comp, + const std::shared_ptr& /*inputGater*/) override { if (mConnection != nullptr) { return ALREADY_EXISTS; } @@ -191,8 +192,9 @@ public: } ~GraphicBufferSourceWrapper() override = default; - status_t connect(const std::shared_ptr &comp) override { - mNode = new C2OMXNode(comp); + status_t connect(const std::shared_ptr &comp, + const std::shared_ptr &inputGater) override { + mNode = new C2OMXNode(comp, inputGater); mNode->setFrameSize(mWidth, mHeight); // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we @@ -373,6 +375,7 @@ private: sp mNode; uint32_t mWidth; uint32_t mHeight; + std::shared_ptr mInputGater; Config mConfig; }; diff --git a/media/sfplugin/CCodecBufferChannel.cpp b/media/sfplugin/CCodecBufferChannel.cpp index 2cdea6e..d6d6d68 100644 --- a/media/sfplugin/CCodecBufferChannel.cpp +++ b/media/sfplugin/CCodecBufferChannel.cpp @@ -1428,6 +1428,31 @@ bool CCodecBufferChannel::PipelineCapacity::allocate(const char* callerTag) { return false; } +bool CCodecBufferChannel::PipelineCapacity::allocateOutput(const char* callerTag) { + int prevComponent = component.fetch_sub(1, std::memory_order_relaxed); + int prevOutput = output.fetch_sub(1, std::memory_order_relaxed); + if (prevComponent > 0 && prevOutput > 1) { // One output reserved for csd. + ALOGV("[%s] %s -- PipelineCapacity::allocateOutput() returns true: " + "pipeline availability -1 output and -1 component ==> " + "input = %d, component = %d, output = %d", + mName, callerTag ? callerTag : "*", + input.load(std::memory_order_relaxed), + prevComponent - 1, + prevOutput - 1); + return true; + } + component.fetch_add(1, std::memory_order_relaxed); + output.fetch_add(1, std::memory_order_relaxed); + ALOGV("[%s] %s -- PipelineCapacity::allocateOutput() returns false: " + "pipeline availability unchanged ==> " + "input = %d, component = %d, output = %d", + mName, callerTag ? callerTag : "*", + input.load(std::memory_order_relaxed), + prevComponent, + prevOutput); + return false; +} + void CCodecBufferChannel::PipelineCapacity::free(const char* callerTag) { int prevInput = input.fetch_add(1, std::memory_order_relaxed); int prevComponent = component.fetch_add(1, std::memory_order_relaxed); @@ -1484,6 +1509,23 @@ int CCodecBufferChannel::PipelineCapacity::freeOutputSlot( return prevOutput + 1; } +// InputGater +struct CCodecBufferChannel::InputGater : public InputSurfaceWrapper::InputGater { + InputGater(const std::shared_ptr& owner) + : mOwner(owner) {} + virtual bool canQueue() override { + std::shared_ptr owner = mOwner.lock(); + if (!owner) { + return false; + } + QueueGuard guard(owner->mSync); + return guard.isRunning() && + owner->mAvailablePipelineCapacity.allocateOutput("InputGater"); + } +private: + std::weak_ptr mOwner; +}; + // CCodecBufferChannel CCodecBufferChannel::CCodecBufferChannel( @@ -1517,7 +1559,8 @@ status_t CCodecBufferChannel::setInputSurface( const std::shared_ptr &surface) { ALOGV("[%s] setInputSurface", mName); mInputSurface = surface; - return mInputSurface->connect(mComponent); + mInputGater = std::make_shared(shared_from_this()); + return mInputSurface->connect(mComponent, mInputGater); } status_t CCodecBufferChannel::signalEndOfInputStream() { @@ -2318,6 +2361,7 @@ void CCodecBufferChannel::stop() { if (mInputSurface != nullptr) { mInputSurface.reset(); } + mInputGater.reset(); } void CCodecBufferChannel::flush(const std::list> &flushedWork) { diff --git a/media/sfplugin/CCodecBufferChannel.h b/media/sfplugin/CCodecBufferChannel.h index 86739ab..3ef58be 100644 --- a/media/sfplugin/CCodecBufferChannel.h +++ b/media/sfplugin/CCodecBufferChannel.h @@ -308,6 +308,18 @@ private: // onInputBufferAvailable() can (and will) be called afterwards. bool allocate(const char* callerTag = nullptr); + // Return true and decrease #component and #output by one if they are + // all greater than zero; return false otherwise. + // + // callerTag is used for logging only. + // + // allocateOutput() is called by CCodecBufferChannel::InputGater to + // check whether the component can accept a queue operation. This is + // used when the input comes from an input surface rather than from + // queueInputBuffer(). Calling allocateOutput() is similar to calling + // allocate() when the input capacity is infinite. + bool allocateOutput(const char* callerTag = nullptr); + // Increase #input, #component and #output by one. // // callerTag is used for logging only. @@ -356,6 +368,9 @@ private: inline bool hasCryptoOrDescrambler() { return mCrypto != NULL || mDescrambler != NULL; } + + struct InputGater; + std::shared_ptr mInputGater; }; // Conversion of a c2_status_t value to a status_t value may depend on the diff --git a/media/sfplugin/InputSurfaceWrapper.h b/media/sfplugin/InputSurfaceWrapper.h index d9c4eec..12e58b2 100644 --- a/media/sfplugin/InputSurfaceWrapper.h +++ b/media/sfplugin/InputSurfaceWrapper.h @@ -33,15 +33,33 @@ public: virtual ~InputSurfaceWrapper() = default; + struct InputGater { + /** + * Try to reserve an input in the pipeline. If this function returns + * true, the pipeline slot is reserved. An implementation of + * InputSurfaceWrapper should not call Component::queue() if canQueue() + * returns false. + * + * \return true if the input can be reserved; false otherwise. + */ + virtual bool canQueue() = 0; + virtual ~InputGater() = default; + }; + /** * Connect the surface with |comp|. A surface can * connect to at most one component at a time. * + * `inputGater->canQueue()` will be called before queuing a buffer. If it + * returns false, the buffer will not be queued to `comp` and simply + * dropped. + * * \return OK successfully connected to |comp| * \return ALREADY_EXISTS already connected to another component. */ virtual status_t connect( - const std::shared_ptr &comp) = 0; + const std::shared_ptr &comp, + const std::shared_ptr &inputGater) = 0; /** * Disconnect the surface from the component if any. -- cgit v1.2.3 From 3b7f04e0e705848c7b0a680a0a61e8ba25ed29b6 Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Fri, 10 May 2019 19:35:34 -0700 Subject: Change libvpx to shared library Bug: 132466615 Test: Build and flash Change-Id: Ib26f05ec6e04a02214fd5717bea6faadfcf4d8f9 --- media/codecs/vpx/Android.bp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/media/codecs/vpx/Android.bp b/media/codecs/vpx/Android.bp index c09f365..cc83371 100644 --- a/media/codecs/vpx/Android.bp +++ b/media/codecs/vpx/Android.bp @@ -7,7 +7,7 @@ cc_library_shared { srcs: ["C2SoftVpxDec.cpp"], - static_libs: ["libvpx"], + shared_libs: ["libvpx"], cflags: [ "-DVP9", @@ -23,7 +23,7 @@ cc_library_shared { srcs: ["C2SoftVpxDec.cpp"], - static_libs: ["libvpx"], + shared_libs: ["libvpx"], } cc_library_shared { @@ -38,7 +38,7 @@ cc_library_shared { "C2SoftVpxEnc.cpp", ], - static_libs: ["libvpx"], + shared_libs: ["libvpx"], cflags: ["-DVP9"], } @@ -55,6 +55,6 @@ cc_library_shared { "C2SoftVpxEnc.cpp", ], - static_libs: ["libvpx"], + shared_libs: ["libvpx"], } -- cgit v1.2.3 From 9277a2eef39e07442ab2d761c2e1dbc9703ea75a Mon Sep 17 00:00:00 2001 From: Hangyu Kuang Date: Wed, 15 May 2019 16:40:56 -0700 Subject: ECOService: Add support for handling actual bitrate stats. Bug: 117877984 Test: Unit test. Change-Id: Iaa3c6425c0cbebdc09af035a42358c452cb163c5 --- media/eco/ECOSession.cpp | 10 +++++++--- media/eco/include/eco/ECODataKey.h | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/media/eco/ECOSession.cpp b/media/eco/ECOSession.cpp index 752df4e..1bdfa61 100644 --- a/media/eco/ECOSession.cpp +++ b/media/eco/ECOSession.cpp @@ -299,9 +299,13 @@ void ECOSession::processFrameStats(const ECOData& stats) { const ECOData::ECODataValueType value = entry.second; ECOLOGD("Processing %s key", key.c_str()); - // Only process the keys that are supported by ECOService 1.0. - if (!key.compare(FRAME_NUM) || !key.compare(FRAME_PTS_US) || !key.compare(FRAME_TYPE) || - !key.compare(FRAME_SIZE_BYTES)) { + if (!key.compare(KEY_STATS_TYPE)) { + // Skip the key KEY_STATS_TYPE as that has been parsed already. + continue; + } else if (!key.compare(FRAME_NUM) || !key.compare(FRAME_PTS_US) || + !key.compare(FRAME_TYPE) || !key.compare(FRAME_SIZE_BYTES) || + !key.compare(ENCODER_ACTUAL_BITRATE_BPS)) { + // Only process the keys that are supported by ECOService 1.0. info.set(key, value); } else if (!key.compare(FRAME_AVG_QP)) { // Check the qp to see if need to notify the listener. diff --git a/media/eco/include/eco/ECODataKey.h b/media/eco/include/eco/ECODataKey.h index 7c59ae0..c70c328 100644 --- a/media/eco/include/eco/ECODataKey.h +++ b/media/eco/include/eco/ECODataKey.h @@ -81,8 +81,8 @@ constexpr char ENCODER_INPUT_WIDTH[] = "encoder-input-width"; constexpr char ENCODER_INPUT_HEIGHT[] = "encoder-input-height"; constexpr char ENCODER_OUTPUT_WIDTH[] = "encoder-output-width"; constexpr char ENCODER_OUTPUT_HEIGHT[] = "encoder-output-height"; -constexpr char ENCODER_TARGET_BITRATE_BPS[] = "encoder-target-bitrate-bps"; -constexpr char ENCODER_ACTUAL_BITRATE_BPS[] = "encoder-actual-bitrate-bps"; +constexpr char ENCODER_TARGET_BITRATE_BPS[] = "encoder-target-bitrate-bps"; // Session info +constexpr char ENCODER_ACTUAL_BITRATE_BPS[] = "encoder-actual-bitrate-bps"; // Frame info constexpr char ENCODER_KFI_FRAMES[] = "encoder-kfi-frames"; constexpr char ENCODER_FRAMERATE_FPS[] = "encoder-framerate-fps"; -- cgit v1.2.3