Loading media/libstagefright/codec2/Android.bp +42 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,48 @@ cc_library_shared { ldflags: ["-Wl,-Bsymbolic"], ldflags: ["-Wl,-Bsymbolic"], } } cc_library_shared { name: "libstagefright_simple_c2component", tags: [ "optional", ], srcs: ["SimpleC2Component.cpp"], include_dirs: [ "frameworks/av/media/libstagefright/codec2/include", ], shared_libs: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.mapper@2.0", "libhidlbase", "libion", "liblog", "libstagefright_codec2", "libstagefright_foundation", "libutils", ], static_libs: [ "libstagefright_codec2_vndk", ], sanitize: { misc_undefined: [ "unsigned-integer-overflow", "signed-integer-overflow", ], cfi: true, diag: { cfi: true, }, }, ldflags: ["-Wl,-Bsymbolic"], } subdirs = [ subdirs = [ "tests", "tests", "vndk", "vndk", Loading media/libstagefright/codec2/SimpleC2Component.cpp 0 → 100644 +295 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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. */ #define LOG_NDEBUG 0 #define LOG_TAG "SimpleC2Component" #include <media/stagefright/foundation/ADebug.h> #include <C2PlatformSupport.h> #include <SimpleC2Component.h> namespace android { SimpleC2Component::SimpleC2Component( const std::shared_ptr<C2ComponentInterface> &intf) : mIntf(intf) { } c2_status_t SimpleC2Component::setListener_sm(const std::shared_ptr<C2Component::Listener> &listener) { Mutexed<ExecState>::Locked state(mExecState); if (state->mState == RUNNING) { return C2_BAD_STATE; } state->mListener = listener; return C2_OK; } c2_status_t SimpleC2Component::queue_nb(std::list<std::unique_ptr<C2Work>> * const items) { { Mutexed<ExecState>::Locked state(mExecState); if (state->mState != RUNNING) { return C2_BAD_STATE; } } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); while (!items->empty()) { queue->mQueue.push_back(std::move(items->front())); items->pop_front(); } queue->mCondition.broadcast(); } return C2_OK; } c2_status_t SimpleC2Component::announce_nb(const std::vector<C2WorkOutline> &items) { (void) items; return C2_OMITTED; } c2_status_t SimpleC2Component::flush_sm( flush_mode_t flushThrough, std::list<std::unique_ptr<C2Work>>* const flushedWork) { (void) flushThrough; { Mutexed<ExecState>::Locked state(mExecState); if (state->mState != RUNNING) { return C2_BAD_STATE; } } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); ++queue->mGeneration; while (!queue->mQueue.empty()) { flushedWork->push_back(std::move(queue->mQueue.front())); queue->mQueue.pop_front(); } } { Mutexed<PendingWork>::Locked pending(mPendingWork); while (!pending->empty()) { flushedWork->push_back(std::move(pending->begin()->second)); pending->erase(pending->begin()); } } return onFlush_sm(); } c2_status_t SimpleC2Component::drain_nb(drain_mode_t drainThrough) { (void) drainThrough; { Mutexed<ExecState>::Locked state(mExecState); if (state->mState != RUNNING) { return C2_BAD_STATE; } } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); if (!queue->mQueue.empty()) { const std::unique_ptr<C2Work> &work = queue->mQueue.back(); work->input.flags = (C2BufferPack::flags_t)(work->input.flags | C2BufferPack::FLAG_END_OF_STREAM); return C2_OK; } } return onDrain_nb(); } c2_status_t SimpleC2Component::start() { Mutexed<ExecState>::Locked state(mExecState); if (state->mState == RUNNING) { return C2_BAD_STATE; } bool needsInit = (state->mState == UNINITIALIZED); if (needsInit) { state.unlock(); c2_status_t err = onInit(); if (err != C2_OK) { return err; } state.lock(); } if (!state->mThread.joinable()) { mExitRequested = false; state->mThread = std::thread( [](std::weak_ptr<SimpleC2Component> wp) { while (true) { std::shared_ptr<SimpleC2Component> thiz = wp.lock(); if (!thiz) { return; } if (thiz->exitRequested()) { return; } thiz->processQueue(); } }, shared_from_this()); } state->mState = RUNNING; return C2_OK; } c2_status_t SimpleC2Component::stop() { { Mutexed<ExecState>::Locked state(mExecState); if (state->mState != RUNNING) { return C2_BAD_STATE; } state->mState = STOPPED; } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); queue->mQueue.clear(); } { Mutexed<PendingWork>::Locked pending(mPendingWork); pending->clear(); } c2_status_t err = onStop(); if (err != C2_OK) { return err; } return C2_OK; } void SimpleC2Component::reset() { { Mutexed<ExecState>::Locked state(mExecState); state->mState = UNINITIALIZED; } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); queue->mQueue.clear(); } { Mutexed<PendingWork>::Locked pending(mPendingWork); pending->clear(); } onReset(); } void SimpleC2Component::release() { { Mutexed<ExecState>::Locked state(mExecState); mExitRequested = true; state->mThread.join(); } onRelease(); } std::shared_ptr<C2ComponentInterface> SimpleC2Component::intf() { return mIntf; } namespace { std::vector<std::unique_ptr<C2Work>> vec(std::unique_ptr<C2Work> &work) { std::vector<std::unique_ptr<C2Work>> ret; ret.push_back(std::move(work)); return ret; } } // namespace void SimpleC2Component::finish( uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork) { std::unique_ptr<C2Work> work; { Mutexed<PendingWork>::Locked pending(mPendingWork); if (pending->count(frameIndex) == 0) { return; } work = std::move(pending->at(frameIndex)); pending->erase(frameIndex); } if (work) { fillWork(work); Mutexed<ExecState>::Locked state(mExecState); state->mListener->onWorkDone_nb(shared_from_this(), vec(work)); } } void SimpleC2Component::processQueue() { std::unique_ptr<C2Work> work; uint64_t generation; { Mutexed<WorkQueue>::Locked queue(mWorkQueue); nsecs_t deadline = systemTime() + ms2ns(250); while (queue->mQueue.empty()) { status_t err = queue.waitForConditionRelative( queue->mCondition, std::max(deadline - systemTime(), (nsecs_t)0)); if (err == TIMED_OUT) { return; } } generation = queue->mGeneration; work = std::move(queue->mQueue.front()); queue->mQueue.pop_front(); } if (!work) { return; } // TODO: grab pool ID from intf if (!mOutputBlockPool) { c2_status_t err = GetCodec2BlockPool(C2BlockPool::BASIC_GRAPHIC, shared_from_this(), &mOutputBlockPool); if (err != C2_OK) { Mutexed<ExecState>::Locked state(mExecState); state->mListener->onError_nb(shared_from_this(), err); return; } } bool done = process(work, mOutputBlockPool); { Mutexed<WorkQueue>::Locked queue(mWorkQueue); if (queue->mGeneration != generation) { work->result = C2_NOT_FOUND; queue.unlock(); { Mutexed<ExecState>::Locked state(mExecState); state->mListener->onWorkDone_nb(shared_from_this(), vec(work)); } queue.lock(); return; } } if (done) { Mutexed<ExecState>::Locked state(mExecState); state->mListener->onWorkDone_nb(shared_from_this(), vec(work)); } else { std::unique_ptr<C2Work> unexpected; { Mutexed<PendingWork>::Locked pending(mPendingWork); uint64_t frameIndex = work->input.ordinal.frame_index; if (pending->count(frameIndex) != 0) { unexpected = std::move(pending->at(frameIndex)); pending->erase(frameIndex); } (void) pending->insert({ frameIndex, std::move(work) }); } if (unexpected) { unexpected->result = C2_CORRUPTED; Mutexed<ExecState>::Locked state(mExecState); state->mListener->onWorkDone_nb(shared_from_this(), vec(unexpected)); } } } } // namespace android media/libstagefright/codec2/include/SimpleC2Component.h 0 → 100644 +153 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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 SIMPLE_C2_COMPONENT_H_ #define SIMPLE_C2_COMPONENT_H_ #include <list> #include <thread> #include <unordered_map> #include <C2Component.h> #include <media/stagefright/foundation/Mutexed.h> namespace android { class SimpleC2Component : public C2Component, public std::enable_shared_from_this<SimpleC2Component> { public: SimpleC2Component( const std::shared_ptr<C2ComponentInterface> &intf); virtual ~SimpleC2Component() = default; // C2Component virtual c2_status_t setListener_sm(const std::shared_ptr<C2Component::Listener> &listener) final; virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>> * const items) final; virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) final; virtual c2_status_t flush_sm( flush_mode_t flushThrough, std::list<std::unique_ptr<C2Work>>* const flushedWork) final; virtual c2_status_t drain_nb(drain_mode_t drainThrough) final; virtual c2_status_t start() final; virtual c2_status_t stop() final; virtual void reset() final; virtual void release() final; virtual std::shared_ptr<C2ComponentInterface> intf() final; // for thread inline bool exitRequested() { return mExitRequested; } void processQueue(); protected: /** * Initialize internal states of the component according to the config set * in the interface. * * This method is called during start(), but only at the first invocation or * after reset(). */ virtual c2_status_t onInit() = 0; /** * Stop the component. */ virtual c2_status_t onStop() = 0; /** * Reset the component. */ virtual void onReset() = 0; /** * Release the component. */ virtual void onRelease() = 0; /** * Flush the component. */ virtual c2_status_t onFlush_sm() = 0; /** * Drain the component. */ virtual c2_status_t onDrain_nb() = 0; /** * Process the given work and finish pending work using finish(). * * \param[in,out] work the work to process * \param[in] pool the pool to use for allocating output blocks. * * \retval true |work| is done and ready for return to client * \retval false more data is needed for the |work| to be done; * mark |work| as pending. */ virtual bool process( const std::unique_ptr<C2Work> &work, std::shared_ptr<C2BlockPool> pool) = 0; // for derived classes /** * Finish pending work. * * This method will retrieve the pending work according to |frameIndex| and * feed the work into |fillWork| function. |fillWork| must be * "non-blocking". Once |fillWork| returns the filled work will be returned * to the client. * * \param[in] frameIndex the index of the pending work * \param[in] fillWork the function to fill the retrieved work. */ void finish(uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork); private: const std::shared_ptr<C2ComponentInterface> mIntf; std::atomic_bool mExitRequested; enum { UNINITIALIZED, STOPPED, RUNNING, }; struct ExecState { ExecState() : mState(UNINITIALIZED) {} int mState; std::thread mThread; std::shared_ptr<C2Component::Listener> mListener; }; Mutexed<ExecState> mExecState; struct WorkQueue { Condition mCondition; std::list<std::unique_ptr<C2Work>> mQueue; uint64_t mGeneration; }; Mutexed<WorkQueue> mWorkQueue; typedef std::unordered_map<uint64_t, std::unique_ptr<C2Work>> PendingWork; Mutexed<PendingWork> mPendingWork; std::shared_ptr<C2BlockPool> mOutputBlockPool; SimpleC2Component() = delete; }; } // namespace android #endif // SIMPLE_C2_COMPONENT_H_ media/libstagefright/codec2/vndk/Android.bp +0 −1 Original line number Original line Diff line number Diff line Loading @@ -15,7 +15,6 @@ cc_library_static { include_dirs: [ include_dirs: [ "frameworks/av/media/libstagefright/codec2/include", "frameworks/av/media/libstagefright/codec2/include", "frameworks/av/media/libstagefright/codec2/vndk/include", "frameworks/native/include/media/hardware", "frameworks/native/include/media/hardware", ], ], Loading media/libstagefright/codecs/avcdec/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -67,6 +67,7 @@ cc_library_shared { "libmedia", "libmedia", "libstagefright_codec2", "libstagefright_codec2", "libstagefright_foundation", "libstagefright_foundation", "libstagefright_simple_c2component", "libutils", "libutils", ], ], Loading Loading
media/libstagefright/codec2/Android.bp +42 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,48 @@ cc_library_shared { ldflags: ["-Wl,-Bsymbolic"], ldflags: ["-Wl,-Bsymbolic"], } } cc_library_shared { name: "libstagefright_simple_c2component", tags: [ "optional", ], srcs: ["SimpleC2Component.cpp"], include_dirs: [ "frameworks/av/media/libstagefright/codec2/include", ], shared_libs: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.mapper@2.0", "libhidlbase", "libion", "liblog", "libstagefright_codec2", "libstagefright_foundation", "libutils", ], static_libs: [ "libstagefright_codec2_vndk", ], sanitize: { misc_undefined: [ "unsigned-integer-overflow", "signed-integer-overflow", ], cfi: true, diag: { cfi: true, }, }, ldflags: ["-Wl,-Bsymbolic"], } subdirs = [ subdirs = [ "tests", "tests", "vndk", "vndk", Loading
media/libstagefright/codec2/SimpleC2Component.cpp 0 → 100644 +295 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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. */ #define LOG_NDEBUG 0 #define LOG_TAG "SimpleC2Component" #include <media/stagefright/foundation/ADebug.h> #include <C2PlatformSupport.h> #include <SimpleC2Component.h> namespace android { SimpleC2Component::SimpleC2Component( const std::shared_ptr<C2ComponentInterface> &intf) : mIntf(intf) { } c2_status_t SimpleC2Component::setListener_sm(const std::shared_ptr<C2Component::Listener> &listener) { Mutexed<ExecState>::Locked state(mExecState); if (state->mState == RUNNING) { return C2_BAD_STATE; } state->mListener = listener; return C2_OK; } c2_status_t SimpleC2Component::queue_nb(std::list<std::unique_ptr<C2Work>> * const items) { { Mutexed<ExecState>::Locked state(mExecState); if (state->mState != RUNNING) { return C2_BAD_STATE; } } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); while (!items->empty()) { queue->mQueue.push_back(std::move(items->front())); items->pop_front(); } queue->mCondition.broadcast(); } return C2_OK; } c2_status_t SimpleC2Component::announce_nb(const std::vector<C2WorkOutline> &items) { (void) items; return C2_OMITTED; } c2_status_t SimpleC2Component::flush_sm( flush_mode_t flushThrough, std::list<std::unique_ptr<C2Work>>* const flushedWork) { (void) flushThrough; { Mutexed<ExecState>::Locked state(mExecState); if (state->mState != RUNNING) { return C2_BAD_STATE; } } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); ++queue->mGeneration; while (!queue->mQueue.empty()) { flushedWork->push_back(std::move(queue->mQueue.front())); queue->mQueue.pop_front(); } } { Mutexed<PendingWork>::Locked pending(mPendingWork); while (!pending->empty()) { flushedWork->push_back(std::move(pending->begin()->second)); pending->erase(pending->begin()); } } return onFlush_sm(); } c2_status_t SimpleC2Component::drain_nb(drain_mode_t drainThrough) { (void) drainThrough; { Mutexed<ExecState>::Locked state(mExecState); if (state->mState != RUNNING) { return C2_BAD_STATE; } } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); if (!queue->mQueue.empty()) { const std::unique_ptr<C2Work> &work = queue->mQueue.back(); work->input.flags = (C2BufferPack::flags_t)(work->input.flags | C2BufferPack::FLAG_END_OF_STREAM); return C2_OK; } } return onDrain_nb(); } c2_status_t SimpleC2Component::start() { Mutexed<ExecState>::Locked state(mExecState); if (state->mState == RUNNING) { return C2_BAD_STATE; } bool needsInit = (state->mState == UNINITIALIZED); if (needsInit) { state.unlock(); c2_status_t err = onInit(); if (err != C2_OK) { return err; } state.lock(); } if (!state->mThread.joinable()) { mExitRequested = false; state->mThread = std::thread( [](std::weak_ptr<SimpleC2Component> wp) { while (true) { std::shared_ptr<SimpleC2Component> thiz = wp.lock(); if (!thiz) { return; } if (thiz->exitRequested()) { return; } thiz->processQueue(); } }, shared_from_this()); } state->mState = RUNNING; return C2_OK; } c2_status_t SimpleC2Component::stop() { { Mutexed<ExecState>::Locked state(mExecState); if (state->mState != RUNNING) { return C2_BAD_STATE; } state->mState = STOPPED; } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); queue->mQueue.clear(); } { Mutexed<PendingWork>::Locked pending(mPendingWork); pending->clear(); } c2_status_t err = onStop(); if (err != C2_OK) { return err; } return C2_OK; } void SimpleC2Component::reset() { { Mutexed<ExecState>::Locked state(mExecState); state->mState = UNINITIALIZED; } { Mutexed<WorkQueue>::Locked queue(mWorkQueue); queue->mQueue.clear(); } { Mutexed<PendingWork>::Locked pending(mPendingWork); pending->clear(); } onReset(); } void SimpleC2Component::release() { { Mutexed<ExecState>::Locked state(mExecState); mExitRequested = true; state->mThread.join(); } onRelease(); } std::shared_ptr<C2ComponentInterface> SimpleC2Component::intf() { return mIntf; } namespace { std::vector<std::unique_ptr<C2Work>> vec(std::unique_ptr<C2Work> &work) { std::vector<std::unique_ptr<C2Work>> ret; ret.push_back(std::move(work)); return ret; } } // namespace void SimpleC2Component::finish( uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork) { std::unique_ptr<C2Work> work; { Mutexed<PendingWork>::Locked pending(mPendingWork); if (pending->count(frameIndex) == 0) { return; } work = std::move(pending->at(frameIndex)); pending->erase(frameIndex); } if (work) { fillWork(work); Mutexed<ExecState>::Locked state(mExecState); state->mListener->onWorkDone_nb(shared_from_this(), vec(work)); } } void SimpleC2Component::processQueue() { std::unique_ptr<C2Work> work; uint64_t generation; { Mutexed<WorkQueue>::Locked queue(mWorkQueue); nsecs_t deadline = systemTime() + ms2ns(250); while (queue->mQueue.empty()) { status_t err = queue.waitForConditionRelative( queue->mCondition, std::max(deadline - systemTime(), (nsecs_t)0)); if (err == TIMED_OUT) { return; } } generation = queue->mGeneration; work = std::move(queue->mQueue.front()); queue->mQueue.pop_front(); } if (!work) { return; } // TODO: grab pool ID from intf if (!mOutputBlockPool) { c2_status_t err = GetCodec2BlockPool(C2BlockPool::BASIC_GRAPHIC, shared_from_this(), &mOutputBlockPool); if (err != C2_OK) { Mutexed<ExecState>::Locked state(mExecState); state->mListener->onError_nb(shared_from_this(), err); return; } } bool done = process(work, mOutputBlockPool); { Mutexed<WorkQueue>::Locked queue(mWorkQueue); if (queue->mGeneration != generation) { work->result = C2_NOT_FOUND; queue.unlock(); { Mutexed<ExecState>::Locked state(mExecState); state->mListener->onWorkDone_nb(shared_from_this(), vec(work)); } queue.lock(); return; } } if (done) { Mutexed<ExecState>::Locked state(mExecState); state->mListener->onWorkDone_nb(shared_from_this(), vec(work)); } else { std::unique_ptr<C2Work> unexpected; { Mutexed<PendingWork>::Locked pending(mPendingWork); uint64_t frameIndex = work->input.ordinal.frame_index; if (pending->count(frameIndex) != 0) { unexpected = std::move(pending->at(frameIndex)); pending->erase(frameIndex); } (void) pending->insert({ frameIndex, std::move(work) }); } if (unexpected) { unexpected->result = C2_CORRUPTED; Mutexed<ExecState>::Locked state(mExecState); state->mListener->onWorkDone_nb(shared_from_this(), vec(unexpected)); } } } } // namespace android
media/libstagefright/codec2/include/SimpleC2Component.h 0 → 100644 +153 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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 SIMPLE_C2_COMPONENT_H_ #define SIMPLE_C2_COMPONENT_H_ #include <list> #include <thread> #include <unordered_map> #include <C2Component.h> #include <media/stagefright/foundation/Mutexed.h> namespace android { class SimpleC2Component : public C2Component, public std::enable_shared_from_this<SimpleC2Component> { public: SimpleC2Component( const std::shared_ptr<C2ComponentInterface> &intf); virtual ~SimpleC2Component() = default; // C2Component virtual c2_status_t setListener_sm(const std::shared_ptr<C2Component::Listener> &listener) final; virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>> * const items) final; virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) final; virtual c2_status_t flush_sm( flush_mode_t flushThrough, std::list<std::unique_ptr<C2Work>>* const flushedWork) final; virtual c2_status_t drain_nb(drain_mode_t drainThrough) final; virtual c2_status_t start() final; virtual c2_status_t stop() final; virtual void reset() final; virtual void release() final; virtual std::shared_ptr<C2ComponentInterface> intf() final; // for thread inline bool exitRequested() { return mExitRequested; } void processQueue(); protected: /** * Initialize internal states of the component according to the config set * in the interface. * * This method is called during start(), but only at the first invocation or * after reset(). */ virtual c2_status_t onInit() = 0; /** * Stop the component. */ virtual c2_status_t onStop() = 0; /** * Reset the component. */ virtual void onReset() = 0; /** * Release the component. */ virtual void onRelease() = 0; /** * Flush the component. */ virtual c2_status_t onFlush_sm() = 0; /** * Drain the component. */ virtual c2_status_t onDrain_nb() = 0; /** * Process the given work and finish pending work using finish(). * * \param[in,out] work the work to process * \param[in] pool the pool to use for allocating output blocks. * * \retval true |work| is done and ready for return to client * \retval false more data is needed for the |work| to be done; * mark |work| as pending. */ virtual bool process( const std::unique_ptr<C2Work> &work, std::shared_ptr<C2BlockPool> pool) = 0; // for derived classes /** * Finish pending work. * * This method will retrieve the pending work according to |frameIndex| and * feed the work into |fillWork| function. |fillWork| must be * "non-blocking". Once |fillWork| returns the filled work will be returned * to the client. * * \param[in] frameIndex the index of the pending work * \param[in] fillWork the function to fill the retrieved work. */ void finish(uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork); private: const std::shared_ptr<C2ComponentInterface> mIntf; std::atomic_bool mExitRequested; enum { UNINITIALIZED, STOPPED, RUNNING, }; struct ExecState { ExecState() : mState(UNINITIALIZED) {} int mState; std::thread mThread; std::shared_ptr<C2Component::Listener> mListener; }; Mutexed<ExecState> mExecState; struct WorkQueue { Condition mCondition; std::list<std::unique_ptr<C2Work>> mQueue; uint64_t mGeneration; }; Mutexed<WorkQueue> mWorkQueue; typedef std::unordered_map<uint64_t, std::unique_ptr<C2Work>> PendingWork; Mutexed<PendingWork> mPendingWork; std::shared_ptr<C2BlockPool> mOutputBlockPool; SimpleC2Component() = delete; }; } // namespace android #endif // SIMPLE_C2_COMPONENT_H_
media/libstagefright/codec2/vndk/Android.bp +0 −1 Original line number Original line Diff line number Diff line Loading @@ -15,7 +15,6 @@ cc_library_static { include_dirs: [ include_dirs: [ "frameworks/av/media/libstagefright/codec2/include", "frameworks/av/media/libstagefright/codec2/include", "frameworks/av/media/libstagefright/codec2/vndk/include", "frameworks/native/include/media/hardware", "frameworks/native/include/media/hardware", ], ], Loading
media/libstagefright/codecs/avcdec/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -67,6 +67,7 @@ cc_library_shared { "libmedia", "libmedia", "libstagefright_codec2", "libstagefright_codec2", "libstagefright_foundation", "libstagefright_foundation", "libstagefright_simple_c2component", "libutils", "libutils", ], ], Loading