From 02765cfd34b2b1742ccbf7656312bbf7e7608aab Mon Sep 17 00:00:00 2001 From: Pushkaraj Patil Date: Thu, 22 Jan 2015 18:31:13 +0530 Subject: mm-video-v4l2: vidc: vdec: handle codec config ETB's properly Change semaphore wait logic to handle codec config buffers properly. Due to quick context switch between msg and async threads, component is unnecessarily waiting for input buffer which is already returned by driver. Following points are taken into consideration while code modification 1. Do not use semaphore for counting/condition check, instead use m_queued_codec_config_count under atomic operation. 2. Use semaphore just once to wait for all EBD's with codec config flag. 3. Post semaphore only if we get all EBD's back from driver. 4. Move component state to flush deferred, to avoid unnecessary sem_post operation, as it will mess-up with semaphore counter state. Change-Id: Ie3b0dd9e3479e5e2831233bc31a5abd35140750d --- mm-video-v4l2/vidc/vdec/inc/omx_vdec.h | 3 ++- mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp | 21 +++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h index f27b9977..5d6f1667 100644 --- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h @@ -463,7 +463,8 @@ class omx_vdec: public qc_omx_component OMX_COMPONENT_PAUSE_PENDING =0xB, OMX_COMPONENT_EXECUTE_PENDING =0xC, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING =0xD, - OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED=0xE + OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED=0xE, + OMX_COMPONENT_FLUSH_DEFERRED = 0xF }; // Deferred callback identifiers diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp index a406aa38..4af17c01 100644 --- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp @@ -2350,17 +2350,18 @@ OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, #endif if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)) { - while (android_atomic_add(0, &m_queued_codec_config_count) > 0) { + if (android_atomic_add(0, &m_queued_codec_config_count) > 0) { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 2; DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ", m_queued_codec_config_count); + BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED); if (sem_timedwait(&m_safe_flush, &ts)) { DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers"); - break; } + BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED); } } @@ -7027,18 +7028,14 @@ int omx_vdec::async_message_process (void *context, void* message) vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR; } if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { - int pending_flush_waiters; - - while (pending_flush_waiters = INT_MAX, - sem_getvalue(&omx->m_safe_flush, &pending_flush_waiters), - /* 0 == there /are/ waiters depending on POSIX implementation */ - pending_flush_waiters <= 0 ) { - DEBUG_PRINT_LOW("sem post for %d EBD of CODEC CONFIG buffer", - omx->m_queued_codec_config_count); + + DEBUG_PRINT_LOW("Decrement codec_config buffer counter"); + android_atomic_dec(&omx->m_queued_codec_config_count); + if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) && + BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) { + DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer"); sem_post(&omx->m_safe_flush); } - DEBUG_PRINT_LOW("Reset codec_config buffer counter"); - android_atomic_and(0, &omx->m_queued_codec_config_count); /* no clearer way to set to 0 */ } omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, -- cgit v1.2.3