Fixed three issues
1. don't return INPUT buffers (OUTPUT part was fixed last week) back to omx client without
   making sure flush is completed while handling do flush request from omx client

2. don't send premature flush completion notification from omx component to omx client.
   We need to check whether all pending buffers (seaprately on INPUT and OUTPUT buffers)
   before the flush completion notification/event is sent out to omx client.

3. counter mis-calculation for the number of outstanding input buffers hold by the dsp.

bug - 2442379
diff --git a/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h b/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h
index dd511f4..8a538d8 100644
--- a/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h
+++ b/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h
@@ -973,6 +973,10 @@
     pthread_mutex_t mutexOutputBFromApp;
     pthread_mutex_t mutexInputBFromDSP;
     pthread_mutex_t mutexOutputBFromDSP;
+    VIDDEC_MUTEX inputFlushCompletionMutex;
+    VIDDEC_MUTEX outputFlushCompletionMutex;
+    OMX_BOOL bIsInputFlushPending;
+    OMX_BOOL bIsOutputFlushPending;
     VIDDEC_MUTEX sDynConfigMutex;
     VIDDEC_SEMAPHORE sInSemaphore;
     VIDDEC_SEMAPHORE sOutSemaphore;
diff --git a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c
index 97844e1..611bb2c 100644
--- a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c
+++ b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c
@@ -1869,9 +1869,21 @@
 
     // No buffer flag EOS event needs to be sent for INPUT port
 
-    return pComponentPrivate->cbInfo.EmptyBufferDone(pComponentPrivate->pHandle,
+    OMX_ERRORTYPE ret = pComponentPrivate->cbInfo.EmptyBufferDone(pComponentPrivate->pHandle,
                                                      pComponentPrivate->pHandle->pApplicationPrivate,
                                                      pBufferHeader);
+
+    VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->inputFlushCompletionMutex);
+    OMX_U32 nCountInputBFromDsp = 0;
+    pthread_mutex_lock(&pComponentPrivate->mutexInputBFromDSP);
+    nCountInputBFromDsp = pComponentPrivate->nCountInputBFromDsp;
+    pthread_mutex_unlock(&pComponentPrivate->mutexInputBFromDSP);
+    if (pComponentPrivate->bIsInputFlushPending && nCountInputBFromDsp == 0) {
+        VIDDEC_PTHREAD_MUTEX_SIGNAL(pComponentPrivate->inputFlushCompletionMutex);
+    }
+    VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->inputFlushCompletionMutex);
+
+    return ret;
 }
 
 OMX_ERRORTYPE VIDDEC_FillBufferDone(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BUFFERHEADERTYPE* pBufferHeader)
@@ -1890,9 +1902,21 @@
                                                NULL);
     }
 
-    return pComponentPrivate->cbInfo.FillBufferDone(pComponentPrivate->pHandle,
+    OMX_ERRORTYPE ret = pComponentPrivate->cbInfo.FillBufferDone(pComponentPrivate->pHandle,
                                                      pComponentPrivate->pHandle->pApplicationPrivate,
                                                      pBufferHeader);
+
+    VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->outputFlushCompletionMutex);
+    OMX_U32 nCountOutputBFromDsp = 0;
+    pthread_mutex_lock(&pComponentPrivate->mutexOutputBFromDSP);
+    nCountOutputBFromDsp = pComponentPrivate->nCountOutputBFromDsp;
+    pthread_mutex_unlock(&pComponentPrivate->mutexOutputBFromDSP);
+    if (pComponentPrivate->bIsOutputFlushPending && nCountOutputBFromDsp == 0) {
+        VIDDEC_PTHREAD_MUTEX_SIGNAL(pComponentPrivate->outputFlushCompletionMutex);
+    }
+    VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->outputFlushCompletionMutex);
+
+    return ret;
 }
 /* ========================================================================== */
 /**
@@ -2230,8 +2254,18 @@
         VIDDEC_CircBuf_Flush(pComponentPrivate, VIDDEC_CBUFFER_TIMESTAMP, VIDDEC_INPUT_PORT);
         OMX_VidDec_Return(pComponentPrivate);
         OMX_VidDec_Return(pComponentPrivate);
-        VIDDEC_ReturnBuffers(pComponentPrivate, VIDDEC_INPUT_PORT, OMX_TRUE);
         if(bPass) {
+            VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->inputFlushCompletionMutex);
+            pComponentPrivate->bIsInputFlushPending = OMX_TRUE;
+            OMX_U32 nCountInputBFromDsp = 0;
+            pthread_mutex_lock(&pComponentPrivate->mutexInputBFromDSP);
+            nCountInputBFromDsp = pComponentPrivate->nCountInputBFromDsp;
+            pthread_mutex_unlock(&pComponentPrivate->mutexInputBFromDSP);
+            if (nCountInputBFromDsp > 0) {
+                VIDDEC_PTHREAD_MUTEX_WAIT(pComponentPrivate->inputFlushCompletionMutex);
+            }
+            pComponentPrivate->bIsInputFlushPending = OMX_FALSE;
+            VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->inputFlushCompletionMutex);
             pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
                                                 pComponentPrivate->pHandle->pApplicationPrivate,
                                                 OMX_EventCmdComplete,
@@ -2266,8 +2300,18 @@
         }
         OMX_VidDec_Return(pComponentPrivate);
         OMX_VidDec_Return(pComponentPrivate);
-        // VIDDEC_ReturnBuffers(pComponentPrivate, VIDDEC_OUTPUT_PORT, OMX_TRUE);
         if(bPass) {
+            VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->outputFlushCompletionMutex);
+            pComponentPrivate->bIsOutputFlushPending = OMX_TRUE;
+            OMX_U32 nCountOutputBFromDsp = 0;
+            pthread_mutex_lock(&pComponentPrivate->mutexOutputBFromDSP);
+            nCountOutputBFromDsp = pComponentPrivate->nCountOutputBFromDsp;
+            pthread_mutex_unlock(&pComponentPrivate->mutexOutputBFromDSP);
+            if (nCountOutputBFromDsp > 0) {
+                VIDDEC_PTHREAD_MUTEX_WAIT(pComponentPrivate->outputFlushCompletionMutex);
+            }
+            pComponentPrivate->bIsOutputFlushPending = OMX_FALSE;
+            VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->outputFlushCompletionMutex);
             pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
                                                 pComponentPrivate->pHandle->pApplicationPrivate,
                                                 OMX_EventCmdComplete,
@@ -3816,12 +3860,12 @@
         eError = OMX_ErrorHardware;
         goto EXIT;
     }
+
     eError = DecrementCount (&(pComponentPrivate->nCountOutputBFromApp), &(pComponentPrivate->mutexOutputBFromApp));
     if (eError != OMX_ErrorNone) {
         return eError;
     }
     OMX_PRBUFFER1(pComponentPrivate->dbg, "pBuffHead 0x%p eExecuteToIdle 0x%x\n", pBuffHead, pComponentPrivate->eExecuteToIdle);
-
     if(pBuffHead->pOutputPortPrivate != NULL) {
         pBufferPrivate = (VIDDEC_BUFFER_PRIVATE* )pBuffHead->pOutputPortPrivate;
         if(pComponentPrivate->eLCMLState != VidDec_LCML_State_Unload &&
@@ -6706,7 +6750,7 @@
         eError = OMX_ErrorHardware;
         goto EXIT;
     }
-    eError = IncrementCount (&(pComponentPrivate->nCountInputBFromDsp), &(pComponentPrivate->mutexInputBFromDSP));
+    eError = DecrementCount (&(pComponentPrivate->nCountInputBFromDsp), &(pComponentPrivate->mutexInputBFromDSP));
     if (eError != OMX_ErrorNone) {
         return eError;
     }
diff --git a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c
index 19dd214..d4861d6 100644
--- a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c
+++ b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c
@@ -340,6 +340,10 @@
         eError = OMX_ErrorUndefined;
         return eError;
     }
+    VIDDEC_PTHREAD_MUTEX_INIT(pComponentPrivate->outputFlushCompletionMutex);
+    pComponentPrivate->bIsOutputFlushPending = OMX_FALSE;
+    VIDDEC_PTHREAD_MUTEX_INIT(pComponentPrivate->inputFlushCompletionMutex);
+    pComponentPrivate->bIsInputFlushPending = OMX_FALSE;
     OMX_MALLOC_STRUCT(pComponentPrivate->pPortParamType, OMX_PORT_PARAM_TYPE,pComponentPrivate->nMemUsage[VIDDDEC_Enum_MemLevel0]);
 #ifdef __STD_COMPONENT__
     OMX_MALLOC_STRUCT(pComponentPrivate->pPortParamTypeAudio, OMX_PORT_PARAM_TYPE,pComponentPrivate->nMemUsage[VIDDDEC_Enum_MemLevel0]);
@@ -2369,6 +2373,14 @@
     OMX_PRBUFFER1(pComponentPrivate->dbg, "+++Entering pHandle 0x%p pBuffer 0x%p Index %lu  state %x  nflags  %x  isfirst %x\n",pComponent,
             pBuffHead, pBuffHead->nInputPortIndex,pComponentPrivate->eState,pBuffHead->nFlags,pComponentPrivate->bFirstHeader);
 
+    OMX_BOOL bIsInputFlushPending = OMX_FALSE;
+    VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->inputFlushCompletionMutex);
+    bIsInputFlushPending = pComponentPrivate->bIsInputFlushPending;
+    VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->inputFlushCompletionMutex);
+    if (bIsInputFlushPending) {
+        LOGE("Unable to process any OMX_EmptyThisBuffer requsts with input flush pending");
+        return OMX_ErrorIncorrectStateOperation;
+    }
 #ifdef __PERF_INSTRUMENTATION__
     PERF_ReceivedFrame(pComponentPrivate->pPERF,
                        pBuffHead->pBuffer,
@@ -2449,13 +2461,21 @@
     VIDDEC_BUFFER_PRIVATE* pBufferPrivate = NULL;
     int ret = 0;
     OMX_CONF_CHECK_CMD(pComponent, pBuffHead, OMX_TRUE);
-
     pHandle = (OMX_COMPONENTTYPE *)pComponent;
     pComponentPrivate = (VIDDEC_COMPONENT_PRIVATE *)pHandle->pComponentPrivate;
 
     OMX_PRBUFFER1(pComponentPrivate->dbg, "+++Entering pHandle 0x%p pBuffer 0x%p Index %lu\n",pComponent,
             pBuffHead, pBuffHead->nOutputPortIndex);
 
+    OMX_BOOL bIsOutputFlushPending = OMX_FALSE;
+    VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->outputFlushCompletionMutex);
+    bIsOutputFlushPending = pComponentPrivate->bIsOutputFlushPending;
+    VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->outputFlushCompletionMutex);
+    if (bIsOutputFlushPending) {
+        LOGE("Unable to process any OMX_FillThisBuffer requsts with flush pending");
+        return OMX_ErrorIncorrectStateOperation;
+    }
+
 #ifdef __PERF_INSTRUMENTATION__
     PERF_ReceivedFrame(pComponentPrivate->pPERF,
                        pBuffHead->pBuffer,
@@ -2817,6 +2837,8 @@
     VIDDEC_PTHREAD_MUTEX_DESTROY(pComponentPrivate->sMutex);
     VIDDEC_PTHREAD_SEMAPHORE_DESTROY(pComponentPrivate->sInSemaphore);
     VIDDEC_PTHREAD_SEMAPHORE_DESTROY(pComponentPrivate->sOutSemaphore);
+    VIDDEC_PTHREAD_MUTEX_DESTROY(pComponentPrivate->inputFlushCompletionMutex);
+    VIDDEC_PTHREAD_MUTEX_DESTROY(pComponentPrivate->outputFlushCompletionMutex);
 #endif
     pthread_mutex_destroy(&(pComponentPrivate->mutexInputBFromApp));
     pthread_mutex_destroy(&(pComponentPrivate->mutexOutputBFromApp));