mm-video: vidc: Fix codec config behavior in flush

Send pending codec config data to the driver when flushing.
Reset intermediate buffers handles when input port is
disabled and port buffers are freed.

Bug: 11099331

Signed-off: Leena Winterrowd <lenhardw@codeaurora.org>
Change-Id: Ifd674b71ce04a4be16b564c53122ce5c5e4d92f1
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
index 765af59..02bf093 100755
--- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -959,6 +959,9 @@
         allocate_color_convert_buf client_buffers;
 #endif
         struct video_decoder_capability m_decoder_capability;
+#ifdef _MSM8974_
+        void send_codec_config();
+#endif
 };
 
 #ifdef _MSM8974_
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 e702c62..1cc359c 100755
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
@@ -2156,6 +2156,7 @@
     } else if (cmd == OMX_CommandFlush) {
         DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
                 "with param1: %lu", param1);
+        send_codec_config();
         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
         }
@@ -2208,6 +2209,7 @@
         DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
                 "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()) {
@@ -5178,13 +5180,6 @@
     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
     unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
 
-    if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
-        codec_config_flag = true;
-        DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
-    } else {
-        codec_config_flag = false;
-    }
-
     if (m_state == OMX_StateInvalid) {
         DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
         return OMX_ErrorInvalidState;
@@ -5243,6 +5238,11 @@
         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)",
             buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
     if (arbitrary_bytes) {
@@ -5500,6 +5500,9 @@
         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
         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;
         int ret,r;
@@ -7369,12 +7372,14 @@
         free (m_inp_mem_ptr);
         m_inp_mem_ptr = NULL;
     }
-    /* We just freed all the buffer headers, every thing in m_input_free_q
-     * is now invalid */
+    /* We just freed all the buffer headers, every thing in m_input_free_q,
+     * pdest_frame, and psource_frame is now invalid */
     while (m_input_free_q.m_size) {
         unsigned address, p2, id;
         m_input_free_q.pop_entry(&address, &p2, &id);
     }
+    pdest_frame = NULL;
+    psource_frame = NULL;
     if (drv_ctx.ptr_inputbuffer) {
         DEBUG_PRINT_LOW("\n Free Driver Context pointer");
         free (drv_ctx.ptr_inputbuffer);
@@ -8929,3 +8934,46 @@
     }
     pthread_mutex_unlock(&m_lock);
 }
+
+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("\n Check Queue for codec_config buffer \n");
+        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("\n empty_this_buffer_proxy_arbitrary failure");
+                        omx_report_error();
+                    }
+                } else {
+                    DEBUG_PRINT_LOW("\n 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("\n empty_this_buffer_proxy failure");
+                        omx_report_error ();
+                    }
+                } else {
+                    pending_input_buffers++;
+                    DEBUG_PRINT_LOW("\n 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("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
+                        (OMX_BUFFERHEADERTYPE *)p1);
+                empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
+            }
+        }
+        pthread_mutex_unlock(&m_lock);
+    }
+}