diff options
Diffstat (limited to 'media/libstagefright/omx/OMX.cpp')
-rw-r--r-- | media/libstagefright/omx/OMX.cpp | 157 |
1 files changed, 141 insertions, 16 deletions
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index d44e3a3..39fa27e 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -75,6 +75,102 @@ private: NodeMeta &operator=(const NodeMeta &); }; +//////////////////////////////////////////////////////////////////////////////// + +struct OMX::CallbackDispatcher : public RefBase { + CallbackDispatcher(); + + void post(const omx_message &msg); + +protected: + virtual ~CallbackDispatcher(); + +private: + Mutex mLock; + bool mDone; + Condition mQueueChanged; + List<omx_message> mQueue; + + pthread_t mThread; + + void dispatch(const omx_message &msg); + + static void *ThreadWrapper(void *me); + void threadEntry(); + + CallbackDispatcher(const CallbackDispatcher &); + CallbackDispatcher &operator=(const CallbackDispatcher &); +}; + +OMX::CallbackDispatcher::CallbackDispatcher() + : mDone(false) { + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + pthread_create(&mThread, &attr, ThreadWrapper, this); + + pthread_attr_destroy(&attr); +} + +OMX::CallbackDispatcher::~CallbackDispatcher() { + { + Mutex::Autolock autoLock(mLock); + + mDone = true; + mQueueChanged.signal(); + } + + void *dummy; + pthread_join(mThread, &dummy); +} + +void OMX::CallbackDispatcher::post(const omx_message &msg) { + Mutex::Autolock autoLock(mLock); + mQueue.push_back(msg); + mQueueChanged.signal(); +} + +void OMX::CallbackDispatcher::dispatch(const omx_message &msg) { + NodeMeta *meta = static_cast<NodeMeta *>(msg.node); + + sp<IOMXObserver> observer = meta->observer(); + if (observer.get() != NULL) { + observer->on_message(msg); + } +} + +// static +void *OMX::CallbackDispatcher::ThreadWrapper(void *me) { + static_cast<CallbackDispatcher *>(me)->threadEntry(); + + return NULL; +} + +void OMX::CallbackDispatcher::threadEntry() { + for (;;) { + omx_message msg; + + { + Mutex::Autolock autoLock(mLock); + while (!mDone && mQueue.empty()) { + mQueueChanged.wait(mLock); + } + + if (mDone) { + break; + } + + msg = *mQueue.begin(); + mQueue.erase(mQueue.begin()); + } + + dispatch(msg); + } +} + +//////////////////////////////////////////////////////////////////////////////// + class BufferMeta { public: BufferMeta(OMX *owner, const sp<IMemory> &mem, bool is_backup = false) @@ -154,7 +250,8 @@ OMX_ERRORTYPE OMX::OnFillBufferDone( return meta->owner()->OnFillBufferDone(meta, pBuffer); } -OMX::OMX() { +OMX::OMX() + : mDispatcher(new CallbackDispatcher) { } status_t OMX::list_nodes(List<String8> *list) { @@ -249,6 +346,29 @@ status_t OMX::set_parameter( return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK; } +status_t OMX::get_config( + node_id node, OMX_INDEXTYPE index, + void *params, size_t size) { + Mutex::Autolock autoLock(mLock); + + NodeMeta *meta = static_cast<NodeMeta *>(node); + OMX_ERRORTYPE err = OMX_GetConfig(meta->handle(), index, params); + + return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK; +} + +status_t OMX::set_config( + node_id node, OMX_INDEXTYPE index, + const void *params, size_t size) { + Mutex::Autolock autoLock(mLock); + + NodeMeta *meta = static_cast<NodeMeta *>(node); + OMX_ERRORTYPE err = + OMX_SetConfig(meta->handle(), index, const_cast<void *>(params)); + + return (err != OMX_ErrorNone) ? UNKNOWN_ERROR : OK; +} + status_t OMX::use_buffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer) { @@ -357,15 +477,12 @@ OMX_ERRORTYPE OMX::OnEvent( omx_message msg; msg.type = omx_message::EVENT; - msg.u.event_data.node = meta; + msg.node = meta; msg.u.event_data.event = eEvent; msg.u.event_data.data1 = nData1; msg.u.event_data.data2 = nData2; - sp<IOMXObserver> observer = meta->observer(); - if (observer.get() != NULL) { - observer->on_message(msg); - } + mDispatcher->post(msg); return OMX_ErrorNone; } @@ -376,13 +493,10 @@ OMX_ERRORTYPE OMX::OnEmptyBufferDone( omx_message msg; msg.type = omx_message::EMPTY_BUFFER_DONE; - msg.u.buffer_data.node = meta; + msg.node = meta; msg.u.buffer_data.buffer = pBuffer; - sp<IOMXObserver> observer = meta->observer(); - if (observer.get() != NULL) { - observer->on_message(msg); - } + mDispatcher->post(msg); return OMX_ErrorNone; } @@ -395,7 +509,7 @@ OMX_ERRORTYPE OMX::OnFillBufferDone( omx_message msg; msg.type = omx_message::FILL_BUFFER_DONE; - msg.u.extended_buffer_data.node = meta; + msg.node = meta; msg.u.extended_buffer_data.buffer = pBuffer; msg.u.extended_buffer_data.range_offset = pBuffer->nOffset; msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen; @@ -403,10 +517,7 @@ OMX_ERRORTYPE OMX::OnFillBufferDone( msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp; msg.u.extended_buffer_data.platform_private = pBuffer->pPlatformPrivate; - sp<IOMXObserver> observer = meta->observer(); - if (observer.get() != NULL) { - observer->on_message(msg); - } + mDispatcher->post(msg); return OMX_ErrorNone; } @@ -455,6 +566,20 @@ void OMX::empty_buffer( assert(err == OMX_ErrorNone); } +status_t OMX::get_extension_index( + node_id node, + const char *parameter_name, + OMX_INDEXTYPE *index) { + NodeMeta *node_meta = static_cast<NodeMeta *>(node); + + OMX_ERRORTYPE err = + OMX_GetExtensionIndex( + node_meta->handle(), + const_cast<char *>(parameter_name), index); + + return err == OMX_ErrorNone ? OK : UNKNOWN_ERROR; +} + //////////////////////////////////////////////////////////////////////////////// sp<IOMXRenderer> OMX::createRenderer( |