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,