exynos_omx: multi_thread: add Dynamic resolution change support code.

Added Dynamic resolution change to H.264 Component.

Change-Id: I73a2d1eaa3412199f886a9a4a4a046c234c06350
Signed-off-by: SeungBeom Kim <sbcrux.kim@samsung.com>
Bug: 10192533
diff --git a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c
index 3aaa74f..a456a2b 100644
--- a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c
+++ b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c
@@ -1064,6 +1064,7 @@
         }
 
         free(pCtx->pOutbuf);
+        pCtx->pOutbuf = NULL;
     }
 
     return ret;
@@ -1653,7 +1654,7 @@
     pthread_mutex_t       *pMutex = NULL;
 
     struct v4l2_buffer buf;
-    int value;
+    int value, state;
 
     if (pCtx == NULL) {
         ALOGE("%s: Video context info must be supplied", __func__);
@@ -1702,7 +1703,11 @@
         pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY;
         break;
     case 3:
-        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
+        exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state);
+        if (state == 1) /* Resolution is changed */
+            pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
+        else            /* Decoding is finished */
+            pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED;
         break;
     default:
         pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
@@ -1773,6 +1778,96 @@
 }
 
 /*
+ * [Decoder Buffer OPS] Cleanup Buffer (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Cleanup_Buffer_Inbuf(void *pHandle)
+{
+    ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    struct v4l2_requestbuffers req;
+    int nBufferCount = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __func__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    nBufferCount = 0; /* for clean-up */
+
+    memset(&req, 0, sizeof(req));
+
+    req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    req.count = nBufferCount;
+
+    if (pCtx->bShareInbuf == VIDEO_TRUE)
+        req.memory = pCtx->nMemoryType;
+    else
+        req.memory = V4L2_MEMORY_MMAP;
+
+    if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pCtx->nInbufs = (int)req.count;
+
+    if (pCtx->pInbuf != NULL) {
+        free(pCtx->pInbuf);
+        pCtx->pInbuf = NULL;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Cleanup Buffer (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Cleanup_Buffer_Outbuf(void *pHandle)
+{
+    ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    struct v4l2_requestbuffers req;
+    int nBufferCount = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __func__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    nBufferCount = 0; /* for clean-up */
+
+    memset(&req, 0, sizeof(req));
+
+    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    req.count = nBufferCount;
+
+    if (pCtx->bShareOutbuf == VIDEO_TRUE)
+        req.memory = pCtx->nMemoryType;
+    else
+        req.memory = V4L2_MEMORY_MMAP;
+
+    if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pCtx->nOutbufs = (int)req.count;
+
+    if (pCtx->pOutbuf != NULL) {
+        free(pCtx->pOutbuf);
+        pCtx->pOutbuf = NULL;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
  * [Decoder Buffer OPS] FindIndex (Output)
  */
 static int MFC_Decoder_FindEmpty_Outbuf(void *pHandle)
@@ -1858,7 +1953,7 @@
 
     struct v4l2_plane  planes[VIDEO_DECODER_OUTBUF_PLANES];
     struct v4l2_buffer buf;
-    int index, i;
+    int state, index, i;
 
     if (pCtx == NULL) {
         ALOGE("%s: Video context info must be supplied", __func__);
@@ -1925,15 +2020,22 @@
     pthread_mutex_unlock(pMutex);
 
     if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) {
-        ALOGE("%s: Failed to enqueue output buffer", __func__);
         pthread_mutex_lock(pMutex);
         pCtx->pOutbuf[buf.index].nIndexUseCnt--;
         pCtx->pOutbuf[buf.index].pPrivate = NULL;
         pCtx->pOutbuf[buf.index].bQueued  = VIDEO_FALSE;
         if (pCtx->pOutbuf[buf.index].nIndexUseCnt == 0)
             pCtx->pOutbuf[buf.index].bSlotUsed = VIDEO_FALSE;
+        exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state);
         pthread_mutex_unlock(pMutex);
-        ret = VIDEO_ERROR_APIFAIL;
+
+        if (state == 1) {
+            /* The case of Resolution is changed */
+            ret = VIDEO_ERROR_WRONGBUFFERSIZE;
+        } else {
+            ALOGE("%s: Failed to enqueue output buffer", __func__);
+            ret = VIDEO_ERROR_APIFAIL;
+        }
         goto EXIT;
     }
 
@@ -1954,7 +2056,7 @@
     ExynosVideoBuffer      *pOutbuf = NULL;
     PrivateDataShareBuffer *pPDSB  = NULL;
     struct v4l2_buffer buf;
-    int value, i, j;
+    int value, state, i, j;
 
     if (pCtx == NULL) {
         ALOGE("%s: Video context info must be supplied", __func__);
@@ -2000,7 +2102,11 @@
         pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY;
         break;
     case 3:
-        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
+        exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state);
+        if (state == 1) /* Resolution is changed */
+            pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
+        else            /* Decoding is finished */
+            pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED;
         break;
     default:
         pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
@@ -2106,6 +2212,7 @@
     .Register               = MFC_Decoder_Register_Inbuf,
     .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Inbuf,
     .Clear_Queue            = MFC_Decoder_Clear_Queued_Inbuf,
+    .Cleanup_Buffer         = MFC_Decoder_Cleanup_Buffer_Inbuf,
 };
 
 /*
@@ -2127,6 +2234,7 @@
     .Register               = MFC_Decoder_Register_Outbuf,
     .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Outbuf,
     .Clear_Queue            = MFC_Decoder_Clear_Queued_Outbuf,
+    .Cleanup_Buffer         = MFC_Decoder_Cleanup_Buffer_Outbuf,
     .ExtensionEnqueue       = MFC_Decoder_ExtensionEnqueue_Outbuf,
     .ExtensionDequeue       = MFC_Decoder_ExtensionDequeue_Outbuf,
     .Enable_DynamicDPB      = MFC_Decoder_Enable_DynamicDPB,