3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 * @file ExynosVideoDecoder.c
21 * @author Jinsung Yang (jsgood.yang@samsung.com)
24 * 2012.01.15: Initial Version
34 #include <sys/types.h>
36 #include <sys/ioctl.h>
42 #include "ExynosVideoApi.h"
43 #include "ExynosVideoDec.h"
45 /* #define LOG_NDEBUG 0 */
46 #define LOG_TAG "ExynosVideoDecoder"
47 #ifndef TIZEN_FEATURE_E3250 /* build env */
48 #include <utils/Log.h>
50 #include "Exynos_OSAL_Log.h"
54 * [Common] __CodingType_To_V4L2PixelFormat
56 static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType)
58 unsigned int pixelformat = V4L2_PIX_FMT_H264;
61 case VIDEO_CODING_AVC:
62 pixelformat = V4L2_PIX_FMT_H264;
64 case VIDEO_CODING_MPEG4:
65 pixelformat = V4L2_PIX_FMT_MPEG4;
67 case VIDEO_CODING_VP8:
68 pixelformat = V4L2_PIX_FMT_VP8;
70 case VIDEO_CODING_H263:
71 pixelformat = V4L2_PIX_FMT_H263;
73 case VIDEO_CODING_VC1:
74 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G;
76 case VIDEO_CODING_VC1_RCV:
77 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L;
79 case VIDEO_CODING_MPEG2:
80 pixelformat = V4L2_PIX_FMT_MPEG2;
83 pixelformat = V4L2_PIX_FMT_H264;
91 * [Common] __ColorFormatType_To_V4L2PixelFormat
93 static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType)
95 unsigned int pixelformat = V4L2_PIX_FMT_NV12M;
97 switch (colorFormatType) {
98 case VIDEO_COLORFORMAT_NV12_TILED:
100 pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
102 pixelformat = V4L2_PIX_FMT_NV12MT;
106 case VIDEO_COLORFORMAT_NV21:
107 pixelformat = V4L2_PIX_FMT_NV21M;
109 case VIDEO_COLORFORMAT_NV12:
112 pixelformat = V4L2_PIX_FMT_NV12M;
122 static void *MFC_Decoder_Init(int nMemoryType)
124 ExynosVideoDecContext *pCtx = NULL;
125 int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING);
129 pCtx = (ExynosVideoDecContext *)malloc(sizeof(*pCtx));
131 ALOGE("%s: Failed to allocate decoder context buffer", __func__);
132 goto EXIT_ALLOC_FAIL;
135 memset(pCtx, 0, sizeof(*pCtx));
137 pCtx->hDec = exynos_v4l2_open_devname(VIDEO_DECODER_NAME, O_RDWR, 0);
138 if (pCtx->hDec < 0) {
139 ALOGE("%s: Failed to open decoder device", __func__);
143 if (!exynos_v4l2_querycap(pCtx->hDec, needCaps)) {
144 ALOGE("%s: Failed to querycap", __func__);
145 goto EXIT_QUERYCAP_FAIL;
148 pCtx->bStreamonInbuf = VIDEO_FALSE;
149 pCtx->bStreamonOutbuf = VIDEO_FALSE;
151 pCtx->nMemoryType = nMemoryType;
153 pCtx->pInMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
154 if (pCtx->pInMutex == NULL) {
155 ALOGE("%s: Failed to allocate mutex about input buffer", __func__);
156 goto EXIT_QUERYCAP_FAIL;
158 if (pthread_mutex_init(pCtx->pInMutex, NULL) != 0) {
159 goto EXIT_QUERYCAP_FAIL;
162 pCtx->pOutMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
163 if (pCtx->pOutMutex == NULL) {
164 ALOGE("%s: Failed to allocate mutex about output buffer", __func__);
165 goto EXIT_QUERYCAP_FAIL;
167 if (pthread_mutex_init(pCtx->pOutMutex, NULL) != 0) {
168 goto EXIT_QUERYCAP_FAIL;
174 if (pCtx->pInMutex != NULL) {
175 pthread_mutex_destroy(pCtx->pInMutex);
176 free(pCtx->pInMutex);
179 if (pCtx->pOutMutex != NULL) {
180 pthread_mutex_destroy(pCtx->pOutMutex);
181 free(pCtx->pOutMutex);
194 * [Decoder OPS] Finalize
196 static ExynosVideoErrorType MFC_Decoder_Finalize(void *pHandle)
198 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
199 ExynosVideoPlane *pVideoPlane = NULL;
200 pthread_mutex_t *pMutex = NULL;
201 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
205 ALOGE("%s: Video context info must be supplied", __func__);
206 ret = VIDEO_ERROR_BADPARAM;
210 if (pCtx->pOutMutex != NULL) {
211 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
212 pthread_mutex_destroy(pMutex);
214 pCtx->pOutMutex = NULL;
217 if (pCtx->pInMutex != NULL) {
218 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
219 pthread_mutex_destroy(pMutex);
221 pCtx->pInMutex = NULL;
224 if (pCtx->bShareInbuf == VIDEO_FALSE) {
225 for (i = 0; i < pCtx->nInbufs; i++) {
226 for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) {
227 pVideoPlane = &pCtx->pInbuf[i].planes[j];
228 if (pVideoPlane->addr != NULL) {
229 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
230 pVideoPlane->addr = NULL;
231 pVideoPlane->allocSize = 0;
232 pVideoPlane->dataSize = 0;
235 pCtx->pInbuf[i].pGeometry = NULL;
236 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
237 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
242 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
243 for (i = 0; i < pCtx->nOutbufs; i++) {
244 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
245 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
246 if (pVideoPlane->addr != NULL) {
247 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
248 pVideoPlane->addr = NULL;
249 pVideoPlane->allocSize = 0;
250 pVideoPlane->dataSize = 0;
253 pCtx->pOutbuf[i].pGeometry = NULL;
254 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
255 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
260 if (pCtx->pInbuf != NULL)
263 if (pCtx->pOutbuf != NULL)
276 * [Decoder OPS] Set Frame Tag
278 static ExynosVideoErrorType MFC_Decoder_Set_FrameTag(
282 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
283 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
284 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
286 ALOGE("%s: Video context info must be supplied", __func__);
287 ret = VIDEO_ERROR_BADPARAM;
291 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) {
292 ret = VIDEO_ERROR_APIFAIL;
302 * [Decoder OPS] Get Frame Tag
304 static int MFC_Decoder_Get_FrameTag(void *pHandle)
306 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
310 ALOGE("%s: Video context info must be supplied", __func__);
313 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
314 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag);
321 * [Decoder OPS] Get Buffer Count
323 static int MFC_Decoder_Get_ActualBufferCount(void *pHandle)
325 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
326 int bufferCount = -1;
329 ALOGE("%s: Video context info must be supplied", __func__);
333 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, &bufferCount);
340 * [Decoder OPS] Set Display Delay
342 static ExynosVideoErrorType MFC_Decoder_Set_DisplayDelay(
346 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
347 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
350 ALOGE("%s: Video context info must be supplied", __func__);
351 ret = VIDEO_ERROR_BADPARAM;
355 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY, delay) != 0) {
356 ret = VIDEO_ERROR_APIFAIL;
364 * [Decoder OPS] Set Immediate Display
366 static ExynosVideoErrorType MFC_Decoder_Set_ImmediateDisplay( void *pHandle)
368 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
369 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
370 #ifdef V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY
372 ALOGE("%s: Video context info must be supplied", __func__);
373 ret = VIDEO_ERROR_BADPARAM;
377 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY, 1) != 0) {
378 ret = VIDEO_ERROR_APIFAIL;
386 * [Decoder OPS] Enable Packed PB
388 static ExynosVideoErrorType MFC_Decoder_Enable_PackedPB(void *pHandle)
390 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
391 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
394 ALOGE("%s: Video context info must be supplied", __func__);
395 ret = VIDEO_ERROR_BADPARAM;
398 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB
399 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB, 1) != 0) {
400 ret = VIDEO_ERROR_APIFAIL;
409 * [Decoder OPS] Enable Loop Filter
411 static ExynosVideoErrorType MFC_Decoder_Enable_LoopFilter(void *pHandle)
413 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
414 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
417 ALOGE("%s: Video context info must be supplied", __func__);
418 ret = VIDEO_ERROR_BADPARAM;
422 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 1) != 0) {
423 ret = VIDEO_ERROR_APIFAIL;
432 * [Decoder OPS] Enable Slice Mode
434 static ExynosVideoErrorType MFC_Decoder_Enable_SliceMode(void *pHandle)
436 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
437 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
440 ALOGE("%s: Video context info must be supplied", __func__);
441 ret = VIDEO_ERROR_BADPARAM;
445 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE, 1) != 0) {
446 ret = VIDEO_ERROR_APIFAIL;
455 * [Decoder OPS] Enable SEI Parsing
457 static ExynosVideoErrorType MFC_Decoder_Enable_SEIParsing(void *pHandle)
459 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
460 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
463 ALOGE("%s: Video context info must be supplied", __func__);
464 ret = VIDEO_ERROR_BADPARAM;
468 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING, 1) != 0) {
469 ret = VIDEO_ERROR_APIFAIL;
478 * [Decoder OPS] Get Frame Packing information
480 static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo(
482 ExynosVideoFramePacking *pFramePacking)
484 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
485 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
486 #ifdef V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL
487 struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM];
488 struct v4l2_ext_controls ext_ctrls;
490 int seiAvailable, seiInfo, seiGridPos;
491 unsigned int seiArgmtId;
494 if ((pCtx == NULL) || (pFramePacking == NULL)) {
495 ALOGE("%s: Video context info or FramePacking pointer must be supplied", __func__);
496 ret = VIDEO_ERROR_BADPARAM;
500 memset(pFramePacking, 0, sizeof(*pFramePacking));
501 memset(ext_ctrl, 0, (sizeof(struct v4l2_ext_control) * FRAME_PACK_SEI_INFO_NUM));
503 ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
504 ext_ctrls.count = FRAME_PACK_SEI_INFO_NUM;
505 ext_ctrls.controls = ext_ctrl;
506 ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL;
507 ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID;
508 ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO;
509 ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS;
511 if (exynos_v4l2_g_ext_ctrl(pCtx->hDec, &ext_ctrls) != 0) {
512 ret = VIDEO_ERROR_APIFAIL;
516 seiAvailable = ext_ctrl[0].value;
517 seiArgmtId = ext_ctrl[1].value;
518 seiInfo = ext_ctrl[2].value;
519 seiGridPos = ext_ctrl[3].value;
521 pFramePacking->available = seiAvailable;
522 pFramePacking->arrangement_id = seiArgmtId;
524 pFramePacking->arrangement_cancel_flag = OPERATE_BIT(seiInfo, 0x1, 0);
525 pFramePacking->arrangement_type = OPERATE_BIT(seiInfo, 0x3f, 1);
526 pFramePacking->quincunx_sampling_flag = OPERATE_BIT(seiInfo, 0x1, 8);
527 pFramePacking->content_interpretation_type = OPERATE_BIT(seiInfo, 0x3f, 9);
528 pFramePacking->spatial_flipping_flag = OPERATE_BIT(seiInfo, 0x1, 15);
529 pFramePacking->frame0_flipped_flag = OPERATE_BIT(seiInfo, 0x1, 16);
530 pFramePacking->field_views_flag = OPERATE_BIT(seiInfo, 0x1, 17);
531 pFramePacking->current_frame_is_frame0_flag = OPERATE_BIT(seiInfo, 0x1, 18);
533 pFramePacking->frame0_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 0);
534 pFramePacking->frame0_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 4);
535 pFramePacking->frame1_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 8);
536 pFramePacking->frame1_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 12);
544 * [Decoder OPS] Enable Decode waiting for share Mode,
545 * to make sure destination support is completed and
546 * reset when Destination streamoff
548 static ExynosVideoErrorType MFC_Decoder_Enable_DecodeWait(void *pHandle)
550 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
551 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
552 #ifdef V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START
554 ALOGE("%s: Video context info must be supplied", __func__);
555 ret = VIDEO_ERROR_BADPARAM;
559 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START, 1) != 0) {
560 ret = VIDEO_ERROR_APIFAIL;
569 * [Decoder Buffer OPS] Enable Cacheable (Input)
571 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Inbuf(void *pHandle)
573 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
574 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
577 ALOGE("%s: Video context info must be supplied", __func__);
578 ret = VIDEO_ERROR_BADPARAM;
581 #ifdef V4L2_CID_CACHEABLE
582 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 2) != 0) {
583 ret = VIDEO_ERROR_APIFAIL;
592 * [Decoder Buffer OPS] Enable Cacheable (Output)
594 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Outbuf(void *pHandle)
596 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
597 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
600 ALOGE("%s: Video context info must be supplied", __func__);
601 ret = VIDEO_ERROR_BADPARAM;
604 #ifdef V4L2_CID_CACHEABLE
605 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 1) != 0) {
606 ret = VIDEO_ERROR_APIFAIL;
615 * [Decoder Buffer OPS] Set Shareable Buffer (Input)
617 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Inbuf(void *pHandle)
619 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
620 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
623 ALOGE("%s: Video context info must be supplied", __func__);
624 ret = VIDEO_ERROR_BADPARAM;
628 pCtx->bShareInbuf = VIDEO_TRUE;
635 * [Decoder Buffer OPS] Set Shareable Buffer (Output)
637 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Outbuf(void *pHandle)
639 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
640 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
643 ALOGE("%s: Video context info must be supplied", __func__);
644 ret = VIDEO_ERROR_BADPARAM;
648 pCtx->bShareOutbuf = VIDEO_TRUE;
655 * [Decoder Buffer OPS] Get Buffer (Input)
657 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Inbuf(
660 ExynosVideoBuffer **pBuffer)
662 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
663 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
666 ALOGE("%s: Video context info must be supplied", __func__);
668 ret = VIDEO_ERROR_BADPARAM;
672 if (pCtx->nInbufs <= nIndex) {
674 ret = VIDEO_ERROR_BADPARAM;
678 *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex];
685 * [Decoder Buffer OPS] Get Buffer (Output)
687 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Outbuf(
690 ExynosVideoBuffer **pBuffer)
692 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
693 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
696 ALOGE("%s: Video context info must be supplied", __func__);
698 ret = VIDEO_ERROR_BADPARAM;
702 if (pCtx->nOutbufs <= nIndex) {
704 ret = VIDEO_ERROR_BADPARAM;
708 *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex];
715 * [Decoder Buffer OPS] Set Geometry (Input)
717 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Inbuf(
719 ExynosVideoGeometry *bufferConf)
721 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
722 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
724 struct v4l2_format fmt;
727 ALOGE("%s: Video context info must be supplied", __func__);
728 ret = VIDEO_ERROR_BADPARAM;
732 if (bufferConf == NULL) {
733 ALOGE("%s: Buffer geometry must be supplied", __func__);
734 ret = VIDEO_ERROR_BADPARAM;
738 memset(&fmt, 0, sizeof(fmt));
740 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
741 fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat);
742 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage;
744 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) {
745 ret = VIDEO_ERROR_APIFAIL;
749 memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry));
756 * [Decoder Buffer OPS] Set Geometry (Output)
758 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Outbuf(
760 ExynosVideoGeometry *bufferConf)
762 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
763 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
765 struct v4l2_format fmt;
768 ALOGE("%s: Video context info must be supplied", __func__);
769 ret = VIDEO_ERROR_BADPARAM;
773 if (bufferConf == NULL) {
774 ALOGE("%s: Buffer geometry must be supplied", __func__);
775 ret = VIDEO_ERROR_BADPARAM;
779 memset(&fmt, 0, sizeof(fmt));
781 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
782 fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat);
784 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) {
785 ret = VIDEO_ERROR_APIFAIL;
789 memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry));
796 * [Decoder Buffer OPS] Get Geometry (Output)
798 static ExynosVideoErrorType MFC_Decoder_Get_Geometry_Outbuf(
800 ExynosVideoGeometry *bufferConf)
802 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
803 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
805 struct v4l2_format fmt;
806 struct v4l2_crop crop;
809 ALOGE("%s: Video context info must be supplied", __func__);
810 ret = VIDEO_ERROR_BADPARAM;
814 if (bufferConf == NULL) {
815 ALOGE("%s: Buffer geometry must be supplied", __func__);
816 ret = VIDEO_ERROR_BADPARAM;
820 memset(&fmt, 0, sizeof(fmt));
821 memset(&crop, 0, sizeof(crop));
823 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
825 if (exynos_v4l2_g_fmt(pCtx->hDec, &fmt) != 0) {
826 ALOGE("%s: exynos_v4l2_g_fmt. ret = %d", __func__, ret);
827 ret = VIDEO_ERROR_APIFAIL;
831 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
833 if (exynos_v4l2_g_crop(pCtx->hDec, &crop) != 0) {
834 ALOGE("%s: exynos_v4l2_g_crop. ret=%d", __func__, ret);
835 ret = VIDEO_ERROR_APIFAIL;
839 bufferConf->nFrameWidth = fmt.fmt.pix_mp.width;
840 bufferConf->nFrameHeight = fmt.fmt.pix_mp.height;
842 bufferConf->cropRect.nTop = crop.c.top;
843 bufferConf->cropRect.nLeft = crop.c.left;
844 bufferConf->cropRect.nWidth = crop.c.width;
845 bufferConf->cropRect.nHeight = crop.c.height;
852 * [Decoder Buffer OPS] Setup (Input)
854 static ExynosVideoErrorType MFC_Decoder_Setup_Inbuf(
856 unsigned int nBufferCount)
858 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
859 ExynosVideoPlane *pVideoPlane = NULL;
860 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
862 struct v4l2_requestbuffers req;
863 struct v4l2_buffer buf;
864 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES];
868 ALOGE("%s: Video context info must be supplied", __func__);
869 ret = VIDEO_ERROR_BADPARAM;
873 if (nBufferCount == 0) {
874 ALOGE("%s: Buffer count must be greater than 0", __func__);
875 ret = VIDEO_ERROR_BADPARAM;
879 ALOGV("%s: setting up inbufs (%d) shared=%s\n", __func__, nBufferCount,
880 pCtx->bShareInbuf ? "true" : "false");
882 memset(&req, 0, sizeof(req));
884 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
885 req.count = nBufferCount;
887 if (pCtx->bShareInbuf == VIDEO_TRUE)
888 req.memory = pCtx->nMemoryType;
890 req.memory = V4L2_MEMORY_MMAP;
892 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
893 ret = VIDEO_ERROR_APIFAIL;
897 if (req.count != nBufferCount) {
898 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count);
899 ret = VIDEO_ERROR_NOMEM;
903 pCtx->nInbufs = (int)req.count;
905 pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
906 if (pCtx->pInbuf == NULL) {
907 ALOGE("Failed to allocate input buffer context");
908 ret = VIDEO_ERROR_NOMEM;
911 memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
913 memset(&buf, 0, sizeof(buf));
915 if (pCtx->bShareInbuf == VIDEO_FALSE) {
916 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
917 buf.memory = V4L2_MEMORY_MMAP;
918 buf.m.planes = planes;
919 buf.length = VIDEO_DECODER_INBUF_PLANES;
921 ALOGV("[%s] INBUF V4L2_MEMORY_MMAP", __func__);
922 for (i = 0; i < pCtx->nInbufs; i++) {
924 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) {
925 ret = VIDEO_ERROR_APIFAIL;
929 pVideoPlane = &pCtx->pInbuf[i].planes[0];
931 pVideoPlane->addr = mmap(NULL,
932 buf.m.planes[0].length, PROT_READ | PROT_WRITE,
933 MAP_SHARED, pCtx->hDec, buf.m.planes[0].m.mem_offset);
935 if (pVideoPlane->addr == MAP_FAILED) {
936 ret = VIDEO_ERROR_MAPFAIL;
940 pVideoPlane->allocSize = buf.m.planes[0].length;
941 pVideoPlane->dataSize = 0;
943 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
944 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
945 pCtx->pInbuf[i].bRegistered = VIDEO_TRUE;
952 if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) {
953 if (pCtx->bShareInbuf == VIDEO_FALSE) {
954 for (i = 0; i < pCtx->nInbufs; i++) {
955 pVideoPlane = &pCtx->pInbuf[i].planes[0];
956 if (pVideoPlane->addr == MAP_FAILED) {
957 pVideoPlane->addr = NULL;
961 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
972 * [Decoder Buffer OPS] Setup (Output)
974 static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf(
976 unsigned int nBufferCount)
978 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
979 ExynosVideoPlane *pVideoPlane = NULL;
980 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
982 struct v4l2_requestbuffers req;
983 struct v4l2_buffer buf;
984 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES];
988 ALOGE("%s: Video context info must be supplied", __func__);
989 ret = VIDEO_ERROR_BADPARAM;
993 if (nBufferCount == 0) {
994 ALOGE("%s: Buffer count must be greater than 0", __func__);
995 ret = VIDEO_ERROR_BADPARAM;
999 ALOGV("%s: setting up outbufs (%d) shared=%s\n", __func__, nBufferCount,
1000 pCtx->bShareOutbuf ? "true" : "false");
1002 memset(&req, 0, sizeof(req));
1004 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1005 req.count = nBufferCount;
1007 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1008 req.memory = pCtx->nMemoryType;
1010 req.memory = V4L2_MEMORY_MMAP;
1012 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1013 ret = VIDEO_ERROR_APIFAIL;
1017 if (req.count != nBufferCount) {
1018 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count);
1019 ret = VIDEO_ERROR_NOMEM;
1023 pCtx->nOutbufs = req.count;
1025 pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1026 if (pCtx->pOutbuf == NULL) {
1027 ALOGE("Failed to allocate output buffer context");
1028 ret = VIDEO_ERROR_NOMEM;
1031 memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1033 memset(&buf, 0, sizeof(buf));
1035 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1036 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1037 buf.memory = V4L2_MEMORY_MMAP;
1038 buf.m.planes = planes;
1039 buf.length = VIDEO_DECODER_OUTBUF_PLANES;
1041 ALOGV("[%s] OUTBUF V4L2_MEMORY_MMAP", __func__);
1042 for (i = 0; i < pCtx->nOutbufs; i++) {
1044 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) {
1045 ret = VIDEO_ERROR_APIFAIL;
1049 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1050 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1051 pVideoPlane->addr = mmap(NULL,
1052 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1053 MAP_SHARED, pCtx->hDec, buf.m.planes[j].m.mem_offset);
1055 if (pVideoPlane->addr == MAP_FAILED) {
1056 ret = VIDEO_ERROR_MAPFAIL;
1060 pVideoPlane->allocSize = buf.m.planes[j].length;
1061 pVideoPlane->dataSize = 0;
1063 #ifdef TIZEN_FEATURE_E3250 /* dmabuf */
1065 if (pCtx->bufShareMethod == BUF_SHARE_FD) {
1066 exynos_v4l2_expbuf(pCtx->hDec, &pVideoPlane->fd, buf.m.planes[j].m.mem_offset);
1067 ALOGV("[%s] fd (%d) received from MFC", __func__, pVideoPlane->fd);
1073 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1074 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1075 pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE;
1082 if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) {
1083 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1084 for (i = 0; i < pCtx->nOutbufs; i++) {
1085 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1086 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1087 if (pVideoPlane->addr == MAP_FAILED) {
1088 pVideoPlane->addr = NULL;
1092 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1097 free(pCtx->pOutbuf);
1104 * [Decoder Buffer OPS] Run (Input)
1106 static ExynosVideoErrorType MFC_Decoder_Run_Inbuf(void *pHandle)
1108 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1109 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1112 ALOGE("%s: Video context info must be supplied", __func__);
1113 ret = VIDEO_ERROR_BADPARAM;
1117 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1118 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1119 ALOGE("%s: Failed to streamon for input buffer", __func__);
1120 ret = VIDEO_ERROR_APIFAIL;
1123 pCtx->bStreamonInbuf = VIDEO_TRUE;
1131 * [Decoder Buffer OPS] Run (Output)
1133 static ExynosVideoErrorType MFC_Decoder_Run_Outbuf(void *pHandle)
1135 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1136 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1139 ALOGE("%s: Video context info must be supplied", __func__);
1140 ret = VIDEO_ERROR_BADPARAM;
1144 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1145 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1146 ALOGE("%s: Failed to streamon for output buffer", __func__);
1147 ret = VIDEO_ERROR_APIFAIL;
1150 pCtx->bStreamonOutbuf = VIDEO_TRUE;
1158 * [Decoder Buffer OPS] Stop (Input)
1160 static ExynosVideoErrorType MFC_Decoder_Stop_Inbuf(void *pHandle)
1162 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1163 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1167 ALOGE("%s: Video context info must be supplied", __func__);
1168 ret = VIDEO_ERROR_BADPARAM;
1172 if (pCtx->bStreamonInbuf == VIDEO_TRUE) {
1173 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1174 ALOGE("%s: Failed to streamoff for input buffer", __func__);
1175 ret = VIDEO_ERROR_APIFAIL;
1178 pCtx->bStreamonInbuf = VIDEO_FALSE;
1181 for (i = 0; i < pCtx->nInbufs; i++) {
1182 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1190 * [Decoder Buffer OPS] Stop (Output)
1192 static ExynosVideoErrorType MFC_Decoder_Stop_Outbuf(void *pHandle)
1194 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1195 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1199 ALOGE("%s: Video context info must be supplied", __func__);
1200 ret = VIDEO_ERROR_BADPARAM;
1204 if (pCtx->bStreamonOutbuf == VIDEO_TRUE) {
1205 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1206 ALOGE("%s: Failed to streamoff for output buffer", __func__);
1207 ret = VIDEO_ERROR_APIFAIL;
1210 pCtx->bStreamonOutbuf = VIDEO_FALSE;
1213 for (i = 0; i < pCtx->nOutbufs; i++) {
1214 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1223 * [Decoder Buffer OPS] Wait (Input)
1225 static ExynosVideoErrorType MFC_Decoder_Wait_Inbuf(void *pHandle)
1227 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1228 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1230 struct pollfd poll_events;
1234 ALOGE("%s: Video context info must be supplied", __func__);
1235 ret = VIDEO_ERROR_BADPARAM;
1239 poll_events.fd = pCtx->hDec;
1240 poll_events.events = POLLOUT | POLLERR;
1241 poll_events.revents = 0;
1244 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_DECODER_POLL_TIMEOUT);
1245 if (poll_state > 0) {
1246 if (poll_events.revents & POLLOUT) {
1249 ALOGE("%s: Poll return error", __func__);
1250 ret = VIDEO_ERROR_POLL;
1253 } else if (poll_state < 0) {
1254 ALOGE("%s: Poll state error", __func__);
1255 ret = VIDEO_ERROR_POLL;
1258 } while (poll_state == 0);
1265 static ExynosVideoErrorType MFC_Decoder_Register_Inbuf(
1267 ExynosVideoPlane *planes,
1270 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1271 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1274 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_INBUF_PLANES)) {
1275 ALOGE("%s: params must be supplied", __func__);
1276 ret = VIDEO_ERROR_BADPARAM;
1280 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1281 if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) {
1282 for (plane = 0; plane < nPlanes; plane++) {
1283 pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr;
1284 pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1285 pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd;
1286 ALOGV("%s: registered buf %d (addr=%p alloc_sz=%ld fd=%d)\n", __func__, nIndex,
1287 planes[plane].addr, planes[plane].allocSize, planes[plane].fd);
1289 pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE;
1294 if (nIndex == pCtx->nInbufs) {
1295 ALOGE("%s: can not find non-registered input buffer", __func__);
1296 ret = VIDEO_ERROR_NOBUFFERS;
1303 static ExynosVideoErrorType MFC_Decoder_Register_Outbuf(
1305 ExynosVideoPlane *planes,
1308 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1309 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1312 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_OUTBUF_PLANES)) {
1313 ALOGE("%s: params must be supplied", __func__);
1314 ret = VIDEO_ERROR_BADPARAM;
1318 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1319 if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) {
1320 for (plane = 0; plane < nPlanes; plane++) {
1321 pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr;
1322 pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1323 pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd;
1324 pCtx->pOutbuf[nIndex].planes[plane].tbm_bo = planes[plane].tbm_bo;
1326 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE;
1327 ALOGV("%s: registered buf %d 0:(addr=%p alloc_sz=%d fd=%d) 1:(addr=%p alloc_sz=%d fd=%d)\n",
1328 __func__, nIndex, planes[0].addr, planes[0].allocSize, planes[0].fd,
1329 planes[1].addr, planes[1].allocSize, planes[1].fd);
1334 if (nIndex == pCtx->nOutbufs) {
1335 ALOGE("%s: can not find non-registered output buffer", __func__);
1336 ret = VIDEO_ERROR_NOBUFFERS;
1343 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
1345 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1346 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1350 ALOGE("%s: Video context info must be supplied", __func__);
1351 ret = VIDEO_ERROR_BADPARAM;
1355 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1356 pCtx->pInbuf[nIndex].planes[0].addr = NULL;
1357 pCtx->pInbuf[nIndex].planes[0].fd = -1;
1358 pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE;
1365 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
1367 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1368 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1372 ALOGE("%s: Video context info must be supplied", __func__);
1373 ret = VIDEO_ERROR_BADPARAM;
1377 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1378 pCtx->pOutbuf[nIndex].planes[0].addr = NULL;
1379 pCtx->pOutbuf[nIndex].planes[0].fd = -1;
1380 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE;
1388 * [Decoder Buffer OPS] Find (Input)
1390 static int MFC_Decoder_Find_Inbuf(
1392 unsigned char *pBuffer)
1394 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1398 ALOGE("%s: Video context info must be supplied", __func__);
1402 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1403 if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) {
1404 if ((pBuffer == NULL) ||
1405 (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer))
1410 if (nIndex == pCtx->nInbufs)
1418 * [Decoder Buffer OPS] Find (Outnput)
1420 static int MFC_Decoder_Find_Outbuf(
1422 unsigned char *pBuffer)
1424 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1428 ALOGE("%s: Video context info must be supplied", __func__);
1432 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1433 if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) {
1434 if ((pBuffer == NULL) ||
1435 (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer))
1440 if (nIndex == pCtx->nOutbufs)
1448 * [Decoder Buffer OPS] Enqueue (Input)
1450 static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf(
1452 unsigned char *pBuffer[],
1453 unsigned int dataSize[],
1457 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1458 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1459 pthread_mutex_t *pMutex = NULL;
1461 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES];
1462 struct v4l2_buffer buf;
1466 ALOGE("%s: Video context info must be supplied", __func__);
1467 ret = VIDEO_ERROR_BADPARAM;
1471 if (VIDEO_DECODER_INBUF_PLANES < nPlanes) {
1472 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1473 VIDEO_DECODER_INBUF_PLANES, nPlanes);
1474 ret = VIDEO_ERROR_BADPARAM;
1478 memset(&buf, 0, sizeof(buf));
1480 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1481 buf.m.planes = planes;
1482 buf.length = VIDEO_DECODER_INBUF_PLANES;
1484 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
1485 pthread_mutex_lock(pMutex);
1486 index = MFC_Decoder_Find_Inbuf(pCtx, pBuffer[0]);
1488 pthread_mutex_unlock(pMutex);
1489 ALOGE("%s: Failed to get index", __func__);
1490 ret = VIDEO_ERROR_NOBUFFERS;
1495 pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE;
1496 pthread_mutex_unlock(pMutex);
1498 if (pCtx->bShareInbuf == VIDEO_TRUE) {
1499 buf.memory = pCtx->nMemoryType;
1500 for (i = 0; i < nPlanes; i++) {
1501 /* V4L2_MEMORY_USERPTR */
1502 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1503 /* V4L2_MEMORY_DMABUF */
1505 buf.m.planes[i].m.fd = pCtx->pInbuf[index].planes[i].fd;
1507 buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize;
1508 buf.m.planes[i].bytesused = dataSize[i];
1509 ALOGV("%s: shared INBUF(%d) plane(%d) data_offset= %x addr=%p len=%d used=%d\n", __func__,
1511 buf.m.planes[i].data_offset,
1512 buf.m.planes[i].m.userptr,
1513 buf.m.planes[i].length,
1514 buf.m.planes[i].bytesused);
1517 buf.memory = V4L2_MEMORY_MMAP;
1518 for (i = 0; i < nPlanes; i++)
1519 buf.m.planes[i].bytesused = dataSize[i];
1522 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) {
1523 ALOGE("%s: Failed to enqueue input buffer", __func__);
1524 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1525 ret = VIDEO_ERROR_APIFAIL;
1529 pCtx->pInbuf[buf.index].pPrivate = pPrivate;
1536 * [Decoder Buffer OPS] Enqueue (Output)
1538 static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf(
1540 unsigned char *pBuffer[],
1541 unsigned int dataSize[],
1545 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1546 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1547 pthread_mutex_t *pMutex = NULL;
1549 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES];
1550 struct v4l2_buffer buf;
1554 ALOGE("%s: Video context info must be supplied", __func__);
1555 ret = VIDEO_ERROR_BADPARAM;
1559 if (VIDEO_DECODER_OUTBUF_PLANES < nPlanes) {
1560 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1561 VIDEO_DECODER_OUTBUF_PLANES, nPlanes);
1562 ret = VIDEO_ERROR_BADPARAM;
1566 memset(&buf, 0, sizeof(buf));
1568 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1569 buf.m.planes = planes;
1570 buf.length = VIDEO_DECODER_OUTBUF_PLANES;
1572 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
1573 pthread_mutex_lock(pMutex);
1574 index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]);
1576 pthread_mutex_unlock(pMutex);
1577 ALOGE("%s: Failed to get index", __func__);
1578 ret = VIDEO_ERROR_NOBUFFERS;
1582 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE;
1583 pthread_mutex_unlock(pMutex);
1585 if (pCtx->bShareOutbuf == VIDEO_TRUE) {
1586 buf.memory = pCtx->nMemoryType;
1587 for (i = 0; i < nPlanes; i++) {
1588 /* V4L2_MEMORY_USERPTR */
1589 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1590 /* V4L2_MEMORY_DMABUF */
1592 buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd;
1594 buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize;
1595 buf.m.planes[i].bytesused = dataSize[i];
1596 ALOGV("%s: shared OUTBUF(%d) plane=%d data_offset= %x addr=0x%lx len=%d used=%d\n", __func__,
1598 buf.m.planes[i].data_offset,
1599 buf.m.planes[i].m.userptr,
1600 buf.m.planes[i].length,
1601 buf.m.planes[i].bytesused);
1604 ALOGV("%s: non-shared outbuf(%d)\n", __func__, index);
1605 buf.memory = V4L2_MEMORY_MMAP;
1608 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) {
1609 ALOGE("%s: Failed to enqueue output buffer", __func__);
1610 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE;
1611 ret = VIDEO_ERROR_APIFAIL;
1615 pCtx->pOutbuf[buf.index].pPrivate = pPrivate;
1622 * [Decoder Buffer OPS] Dequeue (Input)
1624 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle)
1626 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1627 ExynosVideoBuffer *pInbuf = NULL;
1629 struct v4l2_buffer buf;
1632 ALOGE("%s: Video context info must be supplied", __func__);
1636 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1641 memset(&buf, 0, sizeof(buf));
1643 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1645 if (pCtx->bShareInbuf == VIDEO_TRUE)
1646 buf.memory = pCtx->nMemoryType;
1648 buf.memory = V4L2_MEMORY_MMAP;
1650 if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) {
1655 pInbuf = &pCtx->pInbuf[buf.index];
1656 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1658 if (pCtx->bStreamonInbuf == VIDEO_FALSE)
1666 * [Decoder Buffer OPS] Dequeue (Output)
1668 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle)
1670 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1671 ExynosVideoBuffer *pOutbuf = NULL;
1673 struct v4l2_buffer buf;
1679 ALOGE("%s: Video context info must be supplied", __func__);
1683 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1688 memset(&buf, 0, sizeof(buf));
1689 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1691 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1692 buf.memory = pCtx->nMemoryType;
1694 buf.memory = V4L2_MEMORY_MMAP;
1696 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
1697 ret = exynos_v4l2_dqbuf(pCtx->hDec, &buf);
1700 pOutbuf = (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO;
1706 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1711 pOutbuf = &pCtx->pOutbuf[buf.index];
1713 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS
1714 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value);
1716 ALOGV("%s: V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS value = %d", __func__, value);
1719 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY;
1722 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING;
1725 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY;
1728 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state);
1729 if (state == 1) /* Resolution change is detected */
1730 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
1731 else /* Decoding is finished */
1732 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED;
1735 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1739 switch (buf.flags & (0x7 << 3)) {
1741 case V4L2_BUF_FLAG_KEYFRAME:
1742 pOutbuf->frameType = VIDEO_FRAME_I;
1744 case V4L2_BUF_FLAG_PFRAME:
1745 pOutbuf->frameType = VIDEO_FRAME_P;
1747 case V4L2_BUF_FLAG_BFRAME:
1748 pOutbuf->frameType = VIDEO_FRAME_B;
1751 pOutbuf->frameType = VIDEO_FRAME_OTHERS;
1755 pOutbuf->bQueued = VIDEO_FALSE;
1761 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Inbuf(void *pHandle)
1763 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1764 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1768 ALOGE("%s: Video context info must be supplied", __func__);
1769 ret = VIDEO_ERROR_BADPARAM;
1773 for (i = 0; i < pCtx->nInbufs; i++) {
1774 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1781 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Outbuf(void *pHandle)
1783 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1784 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1788 ALOGE("%s: Video context info must be supplied", __func__);
1789 ret = VIDEO_ERROR_BADPARAM;
1793 for (i = 0; i < pCtx->nOutbufs; i++) {
1794 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1801 /* [Decoder Buffer OPS] Cleanup (Input)
1803 static ExynosVideoErrorType MFC_Decoder_Cleanup_Inbuf(void *pHandle)
1805 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1806 ExynosVideoPlane *pVideoPlane = NULL;
1807 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1809 struct v4l2_requestbuffers req;
1810 int nBufferCount, i, j;
1813 ALOGE("%s: Video context info must be supplied", __func__);
1814 ret = VIDEO_ERROR_BADPARAM;
1818 nBufferCount = 0; /* for Clean-up */
1820 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1821 for (i = 0; i < pCtx->nInbufs; i++) {
1822 for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) {
1823 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1824 if (pVideoPlane->addr != NULL) {
1825 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1826 pVideoPlane->addr = NULL;
1827 pVideoPlane->allocSize = 0;
1828 pVideoPlane->dataSize = 0;
1831 pCtx->pInbuf[i].pGeometry = NULL;
1832 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1833 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
1838 memset(&req, 0, sizeof(req));
1840 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1841 req.count = nBufferCount;
1843 if (pCtx->bShareInbuf == VIDEO_TRUE)
1844 req.memory = pCtx->nMemoryType;
1846 req.memory = V4L2_MEMORY_MMAP;
1848 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1849 ret = VIDEO_ERROR_APIFAIL;
1853 pCtx->nInbufs = (int)req.count;
1855 if (pCtx->pInbuf != NULL)
1863 * [Decoder Buffer OPS] Cleanup (Output)
1865 static ExynosVideoErrorType MFC_Decoder_Cleanup_Outbuf(void *pHandle)
1867 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1868 ExynosVideoPlane *pVideoPlane = NULL;
1869 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1871 struct v4l2_requestbuffers req;
1872 int nBufferCount, i ,j;
1875 ALOGE("%s: Video context info must be supplied", __func__);
1876 ret = VIDEO_ERROR_BADPARAM;
1880 nBufferCount = 0; /* for Clean-up */
1882 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1883 for (i = 0; i < pCtx->nOutbufs; i++) {
1884 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1885 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1886 if (pVideoPlane->addr != NULL) {
1887 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1888 pVideoPlane->addr = NULL;
1889 pVideoPlane->allocSize = 0;
1890 pVideoPlane->dataSize = 0;
1893 pCtx->pOutbuf[i].pGeometry = NULL;
1894 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1895 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
1900 memset(&req, 0, sizeof(req));
1902 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1903 req.count = nBufferCount;
1905 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1906 req.memory = pCtx->nMemoryType;
1908 req.memory = V4L2_MEMORY_MMAP;
1910 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1911 ALOGE("reqbuf fail");
1912 ret = VIDEO_ERROR_APIFAIL;
1916 pCtx->nOutbufs = req.count;
1918 if (pCtx->pOutbuf != NULL)
1919 free(pCtx->pOutbuf);
1926 * [Decoder OPS] Common
1928 static ExynosVideoDecOps defDecOps = {
1930 .Init = MFC_Decoder_Init,
1931 .Finalize = MFC_Decoder_Finalize,
1932 .Set_DisplayDelay = MFC_Decoder_Set_DisplayDelay,
1933 .Enable_PackedPB = MFC_Decoder_Enable_PackedPB,
1934 .Enable_LoopFilter = MFC_Decoder_Enable_LoopFilter,
1935 .Enable_SliceMode = MFC_Decoder_Enable_SliceMode,
1936 .Get_ActualBufferCount = MFC_Decoder_Get_ActualBufferCount,
1937 .Set_FrameTag = MFC_Decoder_Set_FrameTag,
1938 .Get_FrameTag = MFC_Decoder_Get_FrameTag,
1939 .Enable_SEIParsing = MFC_Decoder_Enable_SEIParsing,
1940 .Get_FramePackingInfo = MFC_Decoder_Get_FramePackingInfo,
1941 .Set_ImmediateDisplay = MFC_Decoder_Set_ImmediateDisplay,
1942 .Enable_DecodeWait = MFC_Decoder_Enable_DecodeWait,
1946 * [Decoder Buffer OPS] Input
1948 static ExynosVideoDecBufferOps defInbufOps = {
1950 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Inbuf,
1951 .Set_Shareable = MFC_Decoder_Set_Shareable_Inbuf,
1952 .Get_Buffer = MFC_Decoder_Get_Buffer_Inbuf,
1953 .Set_Geometry = MFC_Decoder_Set_Geometry_Inbuf,
1954 .Get_Geometry = NULL,
1955 .Setup = MFC_Decoder_Setup_Inbuf,
1956 .Run = MFC_Decoder_Run_Inbuf,
1957 .Stop = MFC_Decoder_Stop_Inbuf,
1958 .Enqueue = MFC_Decoder_Enqueue_Inbuf,
1959 .Enqueue_All = NULL,
1960 .Dequeue = MFC_Decoder_Dequeue_Inbuf,
1961 .Register = MFC_Decoder_Register_Inbuf,
1962 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Inbuf,
1963 .Clear_Queue = MFC_Decoder_Clear_Queued_Inbuf,
1964 .Cleanup = MFC_Decoder_Cleanup_Inbuf,
1968 * [Decoder Buffer OPS] Output
1970 static ExynosVideoDecBufferOps defOutbufOps = {
1972 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Outbuf,
1973 .Set_Shareable = MFC_Decoder_Set_Shareable_Outbuf,
1974 .Get_Buffer = MFC_Decoder_Get_Buffer_Outbuf,
1975 .Set_Geometry = MFC_Decoder_Set_Geometry_Outbuf,
1976 .Get_Geometry = MFC_Decoder_Get_Geometry_Outbuf,
1977 .Setup = MFC_Decoder_Setup_Outbuf,
1978 .Run = MFC_Decoder_Run_Outbuf,
1979 .Stop = MFC_Decoder_Stop_Outbuf,
1980 .Enqueue = MFC_Decoder_Enqueue_Outbuf,
1981 .Enqueue_All = NULL,
1982 .Dequeue = MFC_Decoder_Dequeue_Outbuf,
1983 .Register = MFC_Decoder_Register_Outbuf,
1984 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Outbuf,
1985 .Clear_Queue = MFC_Decoder_Clear_Queued_Outbuf,
1986 .Cleanup = MFC_Decoder_Cleanup_Outbuf,
1989 int Exynos_Video_Register_Decoder(
1990 ExynosVideoDecOps *pDecOps,
1991 ExynosVideoDecBufferOps *pInbufOps,
1992 ExynosVideoDecBufferOps *pOutbufOps)
1994 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1996 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
1997 ret = VIDEO_ERROR_BADPARAM;
2001 defDecOps.nSize = sizeof(defDecOps);
2002 defInbufOps.nSize = sizeof(defInbufOps);
2003 defOutbufOps.nSize = sizeof(defOutbufOps);
2005 memcpy((char *)pDecOps + sizeof(pDecOps->nSize), (char *)&defDecOps + sizeof(defDecOps.nSize),
2006 pDecOps->nSize - sizeof(pDecOps->nSize));
2008 memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
2009 pInbufOps->nSize - sizeof(pInbufOps->nSize));
2011 memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
2012 pOutbufOps->nSize - sizeof(pOutbufOps->nSize));