Loading media/codec2/sfplugin/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ cc_library_shared { "CCodecConfig.cpp", "Codec2Buffer.cpp", "Codec2InfoBuilder.cpp", "Omx2IGraphicBufferSource.cpp", "PipelineWatcher.cpp", "ReflectedParamUpdater.cpp", "SkipCutBuffer.cpp", Loading media/codec2/sfplugin/CCodec.cpp +48 −53 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <C2ParamInternal.h> #include <C2PlatformSupport.h> #include <android/IGraphicBufferSource.h> #include <android/IOMXBufferSource.h> #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h> #include <android/hardware/media/omx/1.0/IOmx.h> Loading @@ -34,11 +35,8 @@ #include <gui/IGraphicBufferProducer.h> #include <gui/Surface.h> #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> #include <media/omx/1.0/WOmxNode.h> #include <media/openmax/OMX_Core.h> #include <media/omx/1.0/WGraphicBufferSource.h> #include <media/openmax/OMX_IndexExt.h> #include <media/stagefright/omx/1.0/WGraphicBufferSource.h> #include <media/stagefright/omx/OmxGraphicBufferSource.h> #include <media/stagefright/BufferProducerWrapper.h> #include <media/stagefright/MediaCodecConstants.h> #include <media/stagefright/PersistentSurface.h> Loading @@ -47,6 +45,7 @@ #include "CCodec.h" #include "CCodecBufferChannel.h" #include "InputSurfaceWrapper.h" #include "Omx2IGraphicBufferSource.h" extern "C" android::PersistentSurface *CreateInputSurface(); Loading @@ -55,10 +54,9 @@ namespace android { using namespace std::chrono_literals; using ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer; using android::base::StringPrintf; using BGraphicBufferSource = ::android::IGraphicBufferSource; using ::android::hardware::media::c2::V1_0::IInputSurface; typedef hardware::media::omx::V1_0::IGraphicBufferSource HGraphicBufferSource; namespace { class CCodecWatchdog : public AHandler { Loading Loading @@ -182,10 +180,9 @@ private: class GraphicBufferSourceWrapper : public InputSurfaceWrapper { public: typedef hardware::media::omx::V1_0::Status OmxStatus; // explicit GraphicBufferSourceWrapper(const sp<BGraphicBufferSource> &source) : mSource(source) {} GraphicBufferSourceWrapper( const sp<HGraphicBufferSource> &source, const sp<BGraphicBufferSource> &source, uint32_t width, uint32_t height, uint64_t usage) Loading @@ -197,7 +194,6 @@ public: status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override { mNode = new C2OMXNode(comp); mOmxNode = new hardware::media::omx::V1_0::utils::TWOmxNode(mNode); mNode->setFrameSize(mWidth, mHeight); // Usage is queried during configure(), so setting it beforehand. Loading @@ -208,8 +204,7 @@ public: // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we // communicate that directly to the component. mSource->configure( mOmxNode, static_cast<hardware::graphics::common::V1_0::Dataspace>(mDataSpace)); mSource->configure(mNode, mDataSpace); return OK; } Loading @@ -225,16 +220,21 @@ public: source->onOmxIdle(); source->onOmxLoaded(); mNode.clear(); mOmxNode.clear(); } status_t GetStatus(hardware::Return<OmxStatus> &&status) { if (status.isOk()) { return static_cast<status_t>(status.withDefault(OmxStatus::UNKNOWN_ERROR)); } else if (status.isDeadObject()) { return DEAD_OBJECT; status_t GetStatus(const binder::Status &status) { status_t err = OK; if (!status.isOk()) { err = status.serviceSpecificErrorCode(); if (err == OK) { err = status.transactionError(); if (err == OK) { // binder status failed, but there is no servie or transaction error err = UNKNOWN_ERROR; } return UNKNOWN_ERROR; } } return err; } status_t start() override { Loading Loading @@ -359,15 +359,7 @@ public: err = res; } else { status << " delayUs"; hardware::Return<void> trans = mSource->getStopTimeOffsetUs( [&res, &delayUs = config.mInputDelayUs]( auto status, auto stopTimeOffsetUs) { res = static_cast<status_t>(status); delayUs = stopTimeOffsetUs; }); if (!trans.isOk()) { res = trans.isDeadObject() ? DEAD_OBJECT : UNKNOWN_ERROR; } res = GetStatus(mSource->getStopTimeOffsetUs(&config.mInputDelayUs)); if (res != OK) { status << " (=> " << asString(res) << ")"; } else { Loading Loading @@ -396,9 +388,8 @@ public: } private: sp<HGraphicBufferSource> mSource; sp<BGraphicBufferSource> mSource; sp<C2OMXNode> mNode; sp<hardware::media::omx::V1_0::IOmxNode> mOmxNode; uint32_t mWidth; uint32_t mHeight; Config mConfig; Loading Loading @@ -1101,7 +1092,9 @@ sp<PersistentSurface> CCodec::CreateOmxInputSurface() { gbs = source; }); if (transStatus.isOk() && s == OmxStatus::OK) { return new PersistentSurface(new H2BGraphicBufferProducer(gbp), gbs); return new PersistentSurface( new H2BGraphicBufferProducer(gbp), sp<::android::IGraphicBufferSource>(new LWGraphicBufferSource(gbs))); } return nullptr; Loading Loading @@ -1132,28 +1125,28 @@ void CCodec::createInputSurface() { } sp<PersistentSurface> persistentSurface = CreateCompatibleInputSurface(); sp<hidl::base::V1_0::IBase> hidlTarget = persistentSurface->getHidlTarget(); sp<IInputSurface> hidlInputSurface = IInputSurface::castFrom(hidlTarget); sp<HGraphicBufferSource> gbs = HGraphicBufferSource::castFrom(hidlTarget); if (hidlInputSurface) { if (persistentSurface->getHidlTarget()) { sp<IInputSurface> hidlInputSurface = IInputSurface::castFrom( persistentSurface->getHidlTarget()); if (!hidlInputSurface) { ALOGE("Corrupted input surface"); mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR); return; } std::shared_ptr<Codec2Client::InputSurface> inputSurface = std::make_shared<Codec2Client::InputSurface>(hidlInputSurface); err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>( inputSurface)); bufferProducer = inputSurface->getGraphicBufferProducer(); } else if (gbs) { } else { int32_t width = 0; (void)outputFormat->findInt32("width", &width); int32_t height = 0; (void)outputFormat->findInt32("height", &height); err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>( gbs, width, height, usage)); persistentSurface->getBufferSource(), width, height, usage)); bufferProducer = persistentSurface->getBufferProducer(); } else { ALOGE("Corrupted input surface"); mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR); return; } if (err != OK) { Loading Loading @@ -1219,10 +1212,15 @@ void CCodec::setInputSurface(const sp<PersistentSurface> &surface) { outputFormat = config->mOutputFormat; usage = config->mISConfig ? config->mISConfig->mUsage : 0; } sp<hidl::base::V1_0::IBase> hidlTarget = surface->getHidlTarget(); sp<IInputSurface> inputSurface = IInputSurface::castFrom(hidlTarget); sp<HGraphicBufferSource> gbs = HGraphicBufferSource::castFrom(hidlTarget); if (inputSurface) { auto hidlTarget = surface->getHidlTarget(); if (hidlTarget) { sp<IInputSurface> inputSurface = IInputSurface::castFrom(hidlTarget); if (!inputSurface) { ALOGE("Failed to set input surface: Corrupted surface."); mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR); return; } status_t err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>( std::make_shared<Codec2Client::InputSurface>(inputSurface))); if (err != OK) { Loading @@ -1230,22 +1228,18 @@ void CCodec::setInputSurface(const sp<PersistentSurface> &surface) { mCallback->onInputSurfaceDeclined(err); return; } } else if (gbs) { } else { int32_t width = 0; (void)outputFormat->findInt32("width", &width); int32_t height = 0; (void)outputFormat->findInt32("height", &height); status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>( gbs, width, height, usage)); surface->getBufferSource(), width, height, usage)); if (err != OK) { ALOGE("Failed to set up input surface: %d", err); mCallback->onInputSurfaceDeclined(err); return; } } else { ALOGE("Failed to set input surface: Corrupted surface."); mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR); return; } mCallback->onInputSurfaceAccepted(inputFormat, outputFormat); } Loading Loading @@ -1873,7 +1867,6 @@ extern "C" android::CodecBase *CreateCodec() { // Create Codec 2.0 input surface extern "C" android::PersistentSurface *CreateInputSurface() { using namespace android; using ::android::hardware::media::omx::V1_0::implementation::TWGraphicBufferSource; // Attempt to create a Codec2's input surface. std::shared_ptr<Codec2Client::InputSurface> inputSurface = Codec2Client::CreateInputSurface(); Loading @@ -1887,7 +1880,9 @@ extern "C" android::PersistentSurface *CreateInputSurface() { return nullptr; } return new PersistentSurface( gbs->getIGraphicBufferProducer(), new TWGraphicBufferSource(gbs)); gbs->getIGraphicBufferProducer(), sp<IGraphicBufferSource>( new Omx2IGraphicBufferSource(gbs))); } else { return nullptr; } Loading media/codec2/sfplugin/Omx2IGraphicBufferSource.cpp 0 → 100644 +185 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef __LP64__ #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS #endif //#define LOG_NDEBUG 0 #define LOG_TAG "Omx2IGraphicBufferSource" #include <android-base/logging.h> #include "Omx2IGraphicBufferSource.h" #include <android/BnOMXBufferSource.h> #include <media/OMXBuffer.h> #include <media/stagefright/omx/OMXUtils.h> #include <OMX_Component.h> #include <OMX_Index.h> #include <OMX_IndexExt.h> namespace android { namespace /* unnamed */ { // OmxGraphicBufferSource -> IOMXBufferSource struct OmxGbs2IOmxBs : public BnOMXBufferSource { sp<OmxGraphicBufferSource> mBase; OmxGbs2IOmxBs(sp<OmxGraphicBufferSource> const& base) : mBase{base} {} BnStatus onOmxExecuting() override { return mBase->onOmxExecuting(); } BnStatus onOmxIdle() override { return mBase->onOmxIdle(); } BnStatus onOmxLoaded() override { return mBase->onOmxLoaded(); } BnStatus onInputBufferAdded(int32_t bufferId) override { return mBase->onInputBufferAdded(bufferId); } BnStatus onInputBufferEmptied( int32_t bufferId, OMXFenceParcelable const& fenceParcel) override { return mBase->onInputBufferEmptied(bufferId, fenceParcel.get()); } }; struct OmxNodeWrapper : public IOmxNodeWrapper { sp<IOMXNode> mBase; OmxNodeWrapper(sp<IOMXNode> const& base) : mBase{base} {} status_t emptyBuffer( int32_t bufferId, uint32_t flags, const sp<GraphicBuffer> &buffer, int64_t timestamp, int fenceFd) override { return mBase->emptyBuffer(bufferId, buffer, flags, timestamp, fenceFd); } void dispatchDataSpaceChanged( int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override { omx_message msg{}; msg.type = omx_message::EVENT; msg.fenceFd = -1; msg.u.event_data.event = OMX_EventDataSpaceChanged; msg.u.event_data.data1 = dataSpace; msg.u.event_data.data2 = aspects; msg.u.event_data.data3 = pixelFormat; mBase->dispatchMessage(msg); } }; } // unnamed namespace // Omx2IGraphicBufferSource Omx2IGraphicBufferSource::Omx2IGraphicBufferSource( sp<OmxGraphicBufferSource> const& base) : mBase{base}, mOMXBufferSource{new OmxGbs2IOmxBs(base)} { } BnStatus Omx2IGraphicBufferSource::setSuspend( bool suspend, int64_t timeUs) { return BnStatus::fromStatusT(mBase->setSuspend(suspend, timeUs)); } BnStatus Omx2IGraphicBufferSource::setRepeatPreviousFrameDelayUs( int64_t repeatAfterUs) { return BnStatus::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs)); } BnStatus Omx2IGraphicBufferSource::setMaxFps(float maxFps) { return BnStatus::fromStatusT(mBase->setMaxFps(maxFps)); } BnStatus Omx2IGraphicBufferSource::setTimeLapseConfig( double fps, double captureFps) { return BnStatus::fromStatusT(mBase->setTimeLapseConfig(fps, captureFps)); } BnStatus Omx2IGraphicBufferSource::setStartTimeUs( int64_t startTimeUs) { return BnStatus::fromStatusT(mBase->setStartTimeUs(startTimeUs)); } BnStatus Omx2IGraphicBufferSource::setStopTimeUs( int64_t stopTimeUs) { return BnStatus::fromStatusT(mBase->setStopTimeUs(stopTimeUs)); } BnStatus Omx2IGraphicBufferSource::getStopTimeOffsetUs( int64_t *stopTimeOffsetUs) { return BnStatus::fromStatusT(mBase->getStopTimeOffsetUs(stopTimeOffsetUs)); } BnStatus Omx2IGraphicBufferSource::setColorAspects( int32_t aspects) { return BnStatus::fromStatusT(mBase->setColorAspects(aspects)); } BnStatus Omx2IGraphicBufferSource::setTimeOffsetUs( int64_t timeOffsetsUs) { return BnStatus::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs)); } BnStatus Omx2IGraphicBufferSource::signalEndOfInputStream() { return BnStatus::fromStatusT(mBase->signalEndOfInputStream()); } BnStatus Omx2IGraphicBufferSource::configure( const sp<IOMXNode>& omxNode, int32_t dataSpace) { if (omxNode == NULL) { return BnStatus::fromServiceSpecificError(BAD_VALUE); } // Do setInputSurface() first, the node will try to enable metadata // mode on input, and does necessary error checking. If this fails, // we can't use this input surface on the node. status_t err = omxNode->setInputSurface(mOMXBufferSource); if (err != NO_ERROR) { ALOGE("Unable to set input surface: %d", err); return BnStatus::fromServiceSpecificError(err); } uint32_t consumerUsage; if (omxNode->getParameter( (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, &consumerUsage, sizeof(consumerUsage)) != OK) { consumerUsage = 0; } OMX_PARAM_PORTDEFINITIONTYPE def; InitOMXParams(&def); def.nPortIndex = 0; // kPortIndexInput err = omxNode->getParameter( OMX_IndexParamPortDefinition, &def, sizeof(def)); if (err != NO_ERROR) { ALOGE("Failed to get port definition: %d", err); return BnStatus::fromServiceSpecificError(UNKNOWN_ERROR); } return BnStatus::fromStatusT(mBase->configure( new OmxNodeWrapper(omxNode), dataSpace, def.nBufferCountActual, def.format.video.nFrameWidth, def.format.video.nFrameHeight, consumerUsage)); } } // namespace android media/codec2/sfplugin/Omx2IGraphicBufferSource.h 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OMX_2_IGRAPHICBUFFERSOURCE_H_ #define OMX_2_IGRAPHICBUFFERSOURCE_H_ #include <android/BnGraphicBufferSource.h> #include <media/stagefright/omx/OmxGraphicBufferSource.h> namespace android { using BnStatus = ::android::binder::Status; struct Omx2IGraphicBufferSource : public BnGraphicBufferSource { sp<OmxGraphicBufferSource> mBase; sp<IOMXBufferSource> mOMXBufferSource; Omx2IGraphicBufferSource(sp<OmxGraphicBufferSource> const& base); BnStatus configure(const sp<IOMXNode>& omxNode, int32_t dataSpace) override; BnStatus setSuspend(bool suspend, int64_t timeUs) override; BnStatus setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override; BnStatus setMaxFps(float maxFps) override; BnStatus setTimeLapseConfig(double fps, double captureFps) override; BnStatus setStartTimeUs(int64_t startTimeUs) override; BnStatus setStopTimeUs(int64_t stopTimeUs) override; BnStatus getStopTimeOffsetUs(int64_t *stopTimeOffsetUs) override; BnStatus setColorAspects(int32_t aspects) override; BnStatus setTimeOffsetUs(int64_t timeOffsetsUs) override; BnStatus signalEndOfInputStream() override; }; } // namespace android #endif // OMX_2_IGRAPHICBUFFERSOURCE_H_ media/libmedia/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ cc_library_headers { filegroup { name: "libmedia_omx_aidl", srcs: [ "aidl/android/IGraphicBufferSource.aidl", "aidl/android/IOMXBufferSource.aidl", ], path: "aidl", Loading Loading @@ -52,6 +53,7 @@ cc_library_shared { "IOMX.cpp", "MediaCodecBuffer.cpp", "OMXBuffer.cpp", "omx/1.0/WGraphicBufferSource.cpp", "omx/1.0/WOmxBufferSource.cpp", "omx/1.0/WOmxNode.cpp", "omx/1.0/WOmxObserver.cpp", Loading Loading
media/codec2/sfplugin/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ cc_library_shared { "CCodecConfig.cpp", "Codec2Buffer.cpp", "Codec2InfoBuilder.cpp", "Omx2IGraphicBufferSource.cpp", "PipelineWatcher.cpp", "ReflectedParamUpdater.cpp", "SkipCutBuffer.cpp", Loading
media/codec2/sfplugin/CCodec.cpp +48 −53 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <C2ParamInternal.h> #include <C2PlatformSupport.h> #include <android/IGraphicBufferSource.h> #include <android/IOMXBufferSource.h> #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h> #include <android/hardware/media/omx/1.0/IOmx.h> Loading @@ -34,11 +35,8 @@ #include <gui/IGraphicBufferProducer.h> #include <gui/Surface.h> #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> #include <media/omx/1.0/WOmxNode.h> #include <media/openmax/OMX_Core.h> #include <media/omx/1.0/WGraphicBufferSource.h> #include <media/openmax/OMX_IndexExt.h> #include <media/stagefright/omx/1.0/WGraphicBufferSource.h> #include <media/stagefright/omx/OmxGraphicBufferSource.h> #include <media/stagefright/BufferProducerWrapper.h> #include <media/stagefright/MediaCodecConstants.h> #include <media/stagefright/PersistentSurface.h> Loading @@ -47,6 +45,7 @@ #include "CCodec.h" #include "CCodecBufferChannel.h" #include "InputSurfaceWrapper.h" #include "Omx2IGraphicBufferSource.h" extern "C" android::PersistentSurface *CreateInputSurface(); Loading @@ -55,10 +54,9 @@ namespace android { using namespace std::chrono_literals; using ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer; using android::base::StringPrintf; using BGraphicBufferSource = ::android::IGraphicBufferSource; using ::android::hardware::media::c2::V1_0::IInputSurface; typedef hardware::media::omx::V1_0::IGraphicBufferSource HGraphicBufferSource; namespace { class CCodecWatchdog : public AHandler { Loading Loading @@ -182,10 +180,9 @@ private: class GraphicBufferSourceWrapper : public InputSurfaceWrapper { public: typedef hardware::media::omx::V1_0::Status OmxStatus; // explicit GraphicBufferSourceWrapper(const sp<BGraphicBufferSource> &source) : mSource(source) {} GraphicBufferSourceWrapper( const sp<HGraphicBufferSource> &source, const sp<BGraphicBufferSource> &source, uint32_t width, uint32_t height, uint64_t usage) Loading @@ -197,7 +194,6 @@ public: status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override { mNode = new C2OMXNode(comp); mOmxNode = new hardware::media::omx::V1_0::utils::TWOmxNode(mNode); mNode->setFrameSize(mWidth, mHeight); // Usage is queried during configure(), so setting it beforehand. Loading @@ -208,8 +204,7 @@ public: // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we // communicate that directly to the component. mSource->configure( mOmxNode, static_cast<hardware::graphics::common::V1_0::Dataspace>(mDataSpace)); mSource->configure(mNode, mDataSpace); return OK; } Loading @@ -225,16 +220,21 @@ public: source->onOmxIdle(); source->onOmxLoaded(); mNode.clear(); mOmxNode.clear(); } status_t GetStatus(hardware::Return<OmxStatus> &&status) { if (status.isOk()) { return static_cast<status_t>(status.withDefault(OmxStatus::UNKNOWN_ERROR)); } else if (status.isDeadObject()) { return DEAD_OBJECT; status_t GetStatus(const binder::Status &status) { status_t err = OK; if (!status.isOk()) { err = status.serviceSpecificErrorCode(); if (err == OK) { err = status.transactionError(); if (err == OK) { // binder status failed, but there is no servie or transaction error err = UNKNOWN_ERROR; } return UNKNOWN_ERROR; } } return err; } status_t start() override { Loading Loading @@ -359,15 +359,7 @@ public: err = res; } else { status << " delayUs"; hardware::Return<void> trans = mSource->getStopTimeOffsetUs( [&res, &delayUs = config.mInputDelayUs]( auto status, auto stopTimeOffsetUs) { res = static_cast<status_t>(status); delayUs = stopTimeOffsetUs; }); if (!trans.isOk()) { res = trans.isDeadObject() ? DEAD_OBJECT : UNKNOWN_ERROR; } res = GetStatus(mSource->getStopTimeOffsetUs(&config.mInputDelayUs)); if (res != OK) { status << " (=> " << asString(res) << ")"; } else { Loading Loading @@ -396,9 +388,8 @@ public: } private: sp<HGraphicBufferSource> mSource; sp<BGraphicBufferSource> mSource; sp<C2OMXNode> mNode; sp<hardware::media::omx::V1_0::IOmxNode> mOmxNode; uint32_t mWidth; uint32_t mHeight; Config mConfig; Loading Loading @@ -1101,7 +1092,9 @@ sp<PersistentSurface> CCodec::CreateOmxInputSurface() { gbs = source; }); if (transStatus.isOk() && s == OmxStatus::OK) { return new PersistentSurface(new H2BGraphicBufferProducer(gbp), gbs); return new PersistentSurface( new H2BGraphicBufferProducer(gbp), sp<::android::IGraphicBufferSource>(new LWGraphicBufferSource(gbs))); } return nullptr; Loading Loading @@ -1132,28 +1125,28 @@ void CCodec::createInputSurface() { } sp<PersistentSurface> persistentSurface = CreateCompatibleInputSurface(); sp<hidl::base::V1_0::IBase> hidlTarget = persistentSurface->getHidlTarget(); sp<IInputSurface> hidlInputSurface = IInputSurface::castFrom(hidlTarget); sp<HGraphicBufferSource> gbs = HGraphicBufferSource::castFrom(hidlTarget); if (hidlInputSurface) { if (persistentSurface->getHidlTarget()) { sp<IInputSurface> hidlInputSurface = IInputSurface::castFrom( persistentSurface->getHidlTarget()); if (!hidlInputSurface) { ALOGE("Corrupted input surface"); mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR); return; } std::shared_ptr<Codec2Client::InputSurface> inputSurface = std::make_shared<Codec2Client::InputSurface>(hidlInputSurface); err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>( inputSurface)); bufferProducer = inputSurface->getGraphicBufferProducer(); } else if (gbs) { } else { int32_t width = 0; (void)outputFormat->findInt32("width", &width); int32_t height = 0; (void)outputFormat->findInt32("height", &height); err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>( gbs, width, height, usage)); persistentSurface->getBufferSource(), width, height, usage)); bufferProducer = persistentSurface->getBufferProducer(); } else { ALOGE("Corrupted input surface"); mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR); return; } if (err != OK) { Loading Loading @@ -1219,10 +1212,15 @@ void CCodec::setInputSurface(const sp<PersistentSurface> &surface) { outputFormat = config->mOutputFormat; usage = config->mISConfig ? config->mISConfig->mUsage : 0; } sp<hidl::base::V1_0::IBase> hidlTarget = surface->getHidlTarget(); sp<IInputSurface> inputSurface = IInputSurface::castFrom(hidlTarget); sp<HGraphicBufferSource> gbs = HGraphicBufferSource::castFrom(hidlTarget); if (inputSurface) { auto hidlTarget = surface->getHidlTarget(); if (hidlTarget) { sp<IInputSurface> inputSurface = IInputSurface::castFrom(hidlTarget); if (!inputSurface) { ALOGE("Failed to set input surface: Corrupted surface."); mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR); return; } status_t err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>( std::make_shared<Codec2Client::InputSurface>(inputSurface))); if (err != OK) { Loading @@ -1230,22 +1228,18 @@ void CCodec::setInputSurface(const sp<PersistentSurface> &surface) { mCallback->onInputSurfaceDeclined(err); return; } } else if (gbs) { } else { int32_t width = 0; (void)outputFormat->findInt32("width", &width); int32_t height = 0; (void)outputFormat->findInt32("height", &height); status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>( gbs, width, height, usage)); surface->getBufferSource(), width, height, usage)); if (err != OK) { ALOGE("Failed to set up input surface: %d", err); mCallback->onInputSurfaceDeclined(err); return; } } else { ALOGE("Failed to set input surface: Corrupted surface."); mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR); return; } mCallback->onInputSurfaceAccepted(inputFormat, outputFormat); } Loading Loading @@ -1873,7 +1867,6 @@ extern "C" android::CodecBase *CreateCodec() { // Create Codec 2.0 input surface extern "C" android::PersistentSurface *CreateInputSurface() { using namespace android; using ::android::hardware::media::omx::V1_0::implementation::TWGraphicBufferSource; // Attempt to create a Codec2's input surface. std::shared_ptr<Codec2Client::InputSurface> inputSurface = Codec2Client::CreateInputSurface(); Loading @@ -1887,7 +1880,9 @@ extern "C" android::PersistentSurface *CreateInputSurface() { return nullptr; } return new PersistentSurface( gbs->getIGraphicBufferProducer(), new TWGraphicBufferSource(gbs)); gbs->getIGraphicBufferProducer(), sp<IGraphicBufferSource>( new Omx2IGraphicBufferSource(gbs))); } else { return nullptr; } Loading
media/codec2/sfplugin/Omx2IGraphicBufferSource.cpp 0 → 100644 +185 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef __LP64__ #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS #endif //#define LOG_NDEBUG 0 #define LOG_TAG "Omx2IGraphicBufferSource" #include <android-base/logging.h> #include "Omx2IGraphicBufferSource.h" #include <android/BnOMXBufferSource.h> #include <media/OMXBuffer.h> #include <media/stagefright/omx/OMXUtils.h> #include <OMX_Component.h> #include <OMX_Index.h> #include <OMX_IndexExt.h> namespace android { namespace /* unnamed */ { // OmxGraphicBufferSource -> IOMXBufferSource struct OmxGbs2IOmxBs : public BnOMXBufferSource { sp<OmxGraphicBufferSource> mBase; OmxGbs2IOmxBs(sp<OmxGraphicBufferSource> const& base) : mBase{base} {} BnStatus onOmxExecuting() override { return mBase->onOmxExecuting(); } BnStatus onOmxIdle() override { return mBase->onOmxIdle(); } BnStatus onOmxLoaded() override { return mBase->onOmxLoaded(); } BnStatus onInputBufferAdded(int32_t bufferId) override { return mBase->onInputBufferAdded(bufferId); } BnStatus onInputBufferEmptied( int32_t bufferId, OMXFenceParcelable const& fenceParcel) override { return mBase->onInputBufferEmptied(bufferId, fenceParcel.get()); } }; struct OmxNodeWrapper : public IOmxNodeWrapper { sp<IOMXNode> mBase; OmxNodeWrapper(sp<IOMXNode> const& base) : mBase{base} {} status_t emptyBuffer( int32_t bufferId, uint32_t flags, const sp<GraphicBuffer> &buffer, int64_t timestamp, int fenceFd) override { return mBase->emptyBuffer(bufferId, buffer, flags, timestamp, fenceFd); } void dispatchDataSpaceChanged( int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override { omx_message msg{}; msg.type = omx_message::EVENT; msg.fenceFd = -1; msg.u.event_data.event = OMX_EventDataSpaceChanged; msg.u.event_data.data1 = dataSpace; msg.u.event_data.data2 = aspects; msg.u.event_data.data3 = pixelFormat; mBase->dispatchMessage(msg); } }; } // unnamed namespace // Omx2IGraphicBufferSource Omx2IGraphicBufferSource::Omx2IGraphicBufferSource( sp<OmxGraphicBufferSource> const& base) : mBase{base}, mOMXBufferSource{new OmxGbs2IOmxBs(base)} { } BnStatus Omx2IGraphicBufferSource::setSuspend( bool suspend, int64_t timeUs) { return BnStatus::fromStatusT(mBase->setSuspend(suspend, timeUs)); } BnStatus Omx2IGraphicBufferSource::setRepeatPreviousFrameDelayUs( int64_t repeatAfterUs) { return BnStatus::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs)); } BnStatus Omx2IGraphicBufferSource::setMaxFps(float maxFps) { return BnStatus::fromStatusT(mBase->setMaxFps(maxFps)); } BnStatus Omx2IGraphicBufferSource::setTimeLapseConfig( double fps, double captureFps) { return BnStatus::fromStatusT(mBase->setTimeLapseConfig(fps, captureFps)); } BnStatus Omx2IGraphicBufferSource::setStartTimeUs( int64_t startTimeUs) { return BnStatus::fromStatusT(mBase->setStartTimeUs(startTimeUs)); } BnStatus Omx2IGraphicBufferSource::setStopTimeUs( int64_t stopTimeUs) { return BnStatus::fromStatusT(mBase->setStopTimeUs(stopTimeUs)); } BnStatus Omx2IGraphicBufferSource::getStopTimeOffsetUs( int64_t *stopTimeOffsetUs) { return BnStatus::fromStatusT(mBase->getStopTimeOffsetUs(stopTimeOffsetUs)); } BnStatus Omx2IGraphicBufferSource::setColorAspects( int32_t aspects) { return BnStatus::fromStatusT(mBase->setColorAspects(aspects)); } BnStatus Omx2IGraphicBufferSource::setTimeOffsetUs( int64_t timeOffsetsUs) { return BnStatus::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs)); } BnStatus Omx2IGraphicBufferSource::signalEndOfInputStream() { return BnStatus::fromStatusT(mBase->signalEndOfInputStream()); } BnStatus Omx2IGraphicBufferSource::configure( const sp<IOMXNode>& omxNode, int32_t dataSpace) { if (omxNode == NULL) { return BnStatus::fromServiceSpecificError(BAD_VALUE); } // Do setInputSurface() first, the node will try to enable metadata // mode on input, and does necessary error checking. If this fails, // we can't use this input surface on the node. status_t err = omxNode->setInputSurface(mOMXBufferSource); if (err != NO_ERROR) { ALOGE("Unable to set input surface: %d", err); return BnStatus::fromServiceSpecificError(err); } uint32_t consumerUsage; if (omxNode->getParameter( (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, &consumerUsage, sizeof(consumerUsage)) != OK) { consumerUsage = 0; } OMX_PARAM_PORTDEFINITIONTYPE def; InitOMXParams(&def); def.nPortIndex = 0; // kPortIndexInput err = omxNode->getParameter( OMX_IndexParamPortDefinition, &def, sizeof(def)); if (err != NO_ERROR) { ALOGE("Failed to get port definition: %d", err); return BnStatus::fromServiceSpecificError(UNKNOWN_ERROR); } return BnStatus::fromStatusT(mBase->configure( new OmxNodeWrapper(omxNode), dataSpace, def.nBufferCountActual, def.format.video.nFrameWidth, def.format.video.nFrameHeight, consumerUsage)); } } // namespace android
media/codec2/sfplugin/Omx2IGraphicBufferSource.h 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OMX_2_IGRAPHICBUFFERSOURCE_H_ #define OMX_2_IGRAPHICBUFFERSOURCE_H_ #include <android/BnGraphicBufferSource.h> #include <media/stagefright/omx/OmxGraphicBufferSource.h> namespace android { using BnStatus = ::android::binder::Status; struct Omx2IGraphicBufferSource : public BnGraphicBufferSource { sp<OmxGraphicBufferSource> mBase; sp<IOMXBufferSource> mOMXBufferSource; Omx2IGraphicBufferSource(sp<OmxGraphicBufferSource> const& base); BnStatus configure(const sp<IOMXNode>& omxNode, int32_t dataSpace) override; BnStatus setSuspend(bool suspend, int64_t timeUs) override; BnStatus setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override; BnStatus setMaxFps(float maxFps) override; BnStatus setTimeLapseConfig(double fps, double captureFps) override; BnStatus setStartTimeUs(int64_t startTimeUs) override; BnStatus setStopTimeUs(int64_t stopTimeUs) override; BnStatus getStopTimeOffsetUs(int64_t *stopTimeOffsetUs) override; BnStatus setColorAspects(int32_t aspects) override; BnStatus setTimeOffsetUs(int64_t timeOffsetsUs) override; BnStatus signalEndOfInputStream() override; }; } // namespace android #endif // OMX_2_IGRAPHICBUFFERSOURCE_H_
media/libmedia/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ cc_library_headers { filegroup { name: "libmedia_omx_aidl", srcs: [ "aidl/android/IGraphicBufferSource.aidl", "aidl/android/IOMXBufferSource.aidl", ], path: "aidl", Loading Loading @@ -52,6 +53,7 @@ cc_library_shared { "IOMX.cpp", "MediaCodecBuffer.cpp", "OMXBuffer.cpp", "omx/1.0/WGraphicBufferSource.cpp", "omx/1.0/WOmxBufferSource.cpp", "omx/1.0/WOmxNode.cpp", "omx/1.0/WOmxObserver.cpp", Loading