diff options
author | Balamurugan Alagarsamy <balaga@codeaurora.org> | 2015-04-20 21:42:52 +0530 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2015-05-04 12:39:32 -0700 |
commit | f1cb44507b7787a5db1cc04729aeb056c8ce2a5c (patch) | |
tree | 3be2859e7fff83073457cb7c2e08dac4695e748b | |
parent | fac0a22231a57a62007344ec84ea338b520b7b3a (diff) | |
download | android_hardware_qcom_media-stable/cm-12.1-caf-8974-YOG3C.tar.gz android_hardware_qcom_media-stable/cm-12.1-caf-8974-YOG3C.tar.bz2 android_hardware_qcom_media-stable/cm-12.1-caf-8974-YOG3C.zip |
mm-video-v4l2: vidc: vdec: handle flush while codec config ETB for hevc decoderstable/cm-12.1-caf-8974-YOG3C
In case flush arrives while codec-config buffers are sent
to codec, defer sending flush till codec config buffers
are consumed. Also,
- Sends any pending codec config data to the driver when
an OMX_CommandFlush is received
- Flushes all data when the input port is disabled
- Resets source/dest frames to NULL once all input buffers are freed
- Checks the codec config flag after checking for a null buffer
This change comprises of below changes made for venus decoder component.
mm-video: vidc: Fix codec config behavior in flush
mm-video: vidc: defer flush until headers are consumed
mm-video-v4l2: vidc: move flush waiting logic to appropriate place
mm-video-v4l2: vidc: move pending flush sem release in async thread
mm-video-v4l2: vidc: move codec_config buffer counter increment
mm-video-v4l2: vidc: vdec: handle codec config ETB's properly
Change-Id: If484ab187e11eff89f97ef1e5e4ebcc29ec391a5
-rw-r--r-- | mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h | 11 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp | 108 |
2 files changed, 106 insertions, 13 deletions
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h index 9c154621..4dce1236 100644 --- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h @@ -1,5 +1,5 @@ /*-------------------------------------------------------------------------- -Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -47,6 +47,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <string.h> #include <inttypes.h> #include <cstddef> +#include <cutils/atomic.h> #include "SwVdecTypes.h" #include "SwVdecAPI.h" @@ -487,7 +488,8 @@ private: 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 @@ -822,6 +824,7 @@ private: pthread_mutex_t m_lock; pthread_mutex_t c_lock; //sem to handle the minimum procesing of commands + sem_t m_safe_flush; sem_t m_cmd_lock; bool m_error_propogated; // compression format @@ -1080,6 +1083,10 @@ private: int log_output_buffers(OMX_BUFFERHEADERTYPE *); int log_im_buffer(OMX_BUFFERHEADERTYPE * buffer); static OMX_ERRORTYPE describeColorFormat(OMX_PTR params); + volatile int32_t m_queued_codec_config_count; +#ifdef _MSM8974_ + void send_codec_config(); +#endif }; #ifdef _MSM8974_ diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp index 0688eb46..36df0b07 100644 --- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp @@ -1,5 +1,5 @@ /*-------------------------------------------------------------------------- -Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -598,7 +598,8 @@ omx_vdec::omx_vdec(): #endif m_desc_buffer_ptr(NULL), secure_mode(false), - codec_config_flag(false) + codec_config_flag(false), + m_queued_codec_config_count(0) { /* Assumption is that , to begin with , we have all the frames with decoder */ DEBUG_PRINT_HIGH("In OMX vdec Constructor"); @@ -681,6 +682,7 @@ omx_vdec::omx_vdec(): pthread_mutex_init(&m_lock, &attr); pthread_mutex_init(&c_lock, &attr); sem_init(&m_cmd_lock,0,0); + sem_init(&m_safe_flush, 0, 0); streaming[CAPTURE_PORT] = streaming[OUTPUT_PORT] = false; #ifdef _ANDROID_ @@ -2103,6 +2105,7 @@ OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, "to invalid port: %lu", param1); return OMX_ErrorBadPortIndex; } + post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); sem_wait(&m_cmd_lock); DEBUG_PRINT_LOW("send_command: Command Processed"); @@ -2509,6 +2512,26 @@ OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, { DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued" "with param1: %lu", param1); +#ifdef _MSM8974_ + send_codec_config(); +#endif + if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX || + param1 == OMX_ALL)) { + 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"); + } + BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED); + } + } + if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) { BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); @@ -2574,6 +2597,7 @@ OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, "with param1: %lu", param1); if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { + codec_config_flag = false; m_inp_bEnabled = OMX_FALSE; if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) && release_input_done()) @@ -5897,15 +5921,6 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, return OMX_ErrorBadPortIndex; } - if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) - { - codec_config_flag = true; - DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); - } - else - { - codec_config_flag = false; - } #ifdef _ANDROID_ if(iDivXDrmDecrypt) @@ -5953,6 +5968,10 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid"); return OMX_ErrorBadParameter; } + if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + codec_config_flag = true; + DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); + } DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu) nFlags(%x)", buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen, buffer->nFlags); @@ -6182,6 +6201,10 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE h buf.timestamp.tv_sec = frameinfo.timestamp / 1000000; buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000); buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0; + if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + DEBUG_PRINT_LOW("Increment codec_config buffer counter"); + android_atomic_inc(&m_queued_codec_config_count); + } rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); if(rc) @@ -6189,6 +6212,9 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE h DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver"); return OMX_ErrorHardware; } + if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { + codec_config_flag = false; + } if(!streaming[OUTPUT_PORT]) { enum v4l2_buf_type buf_type; @@ -7308,6 +7334,16 @@ int omx_vdec::async_message_process (void *context, void* message) if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) { vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR; } + if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + 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); + } + } + omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, OMX_COMPONENT_GENERATE_EBD); break; @@ -8008,6 +8044,12 @@ void omx_vdec::free_input_buffer_header() unsigned address, p2, id; m_input_free_q.pop_entry(&address, &p2, &id); } + while (m_input_pending_q.m_size) { + unsigned address, p2, id; + m_input_pending_q.pop_entry(&address, &p2, &id); + } + pdest_frame = NULL; + psource_frame = NULL; if (drv_ctx.ptr_inputbuffer) { DEBUG_PRINT_LOW("Free Driver Context pointer"); @@ -10740,3 +10782,47 @@ OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) { #endif //FLEXYUV_SUPPORTED } +#ifdef _MSM8974_ +void omx_vdec::send_codec_config() { + if (codec_config_flag) { + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + pthread_mutex_lock(&m_lock); + DEBUG_PRINT_LOW("Check Queue for codec_config buffer"); + while (m_etb_q.m_size) { + m_etb_q.pop_entry(&p1,&p2,&ident); + if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { + if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure"); + omx_report_error(); + } + } else { + DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); + m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); + } + } else if (ident == OMX_COMPONENT_GENERATE_ETB) { + if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure"); + omx_report_error (); + } + } else { + pending_input_buffers++; + DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", + (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + } else if (ident == OMX_COMPONENT_GENERATE_EBD) { + DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p", + (OMX_BUFFERHEADERTYPE *)p1); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + pthread_mutex_unlock(&m_lock); + } +} +#endif |