summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBalamurugan Alagarsamy <balaga@codeaurora.org>2015-04-20 21:42:52 +0530
committerSteve Kondik <steve@cyngn.com>2015-05-04 12:39:32 -0700
commitf1cb44507b7787a5db1cc04729aeb056c8ce2a5c (patch)
tree3be2859e7fff83073457cb7c2e08dac4695e748b
parentfac0a22231a57a62007344ec84ea338b520b7b3a (diff)
downloadandroid_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.h11
-rw-r--r--mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp108
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