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:
111 pixelformat = V4L2_PIX_FMT_NV12M;
122 static void *MFC_Decoder_Init(int nMemoryType)
124 ExynosVideoDecContext *pCtx = NULL;
125 pthread_mutex_t *pMutex = NULL;
126 int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING);
130 pCtx = (ExynosVideoDecContext *)malloc(sizeof(*pCtx));
132 ALOGE("%s: Failed to allocate decoder context buffer", __func__);
133 goto EXIT_ALLOC_FAIL;
136 memset(pCtx, 0, sizeof(*pCtx));
138 pCtx->hDec = exynos_v4l2_open_devname(VIDEO_DECODER_NAME, O_RDWR, 0);
139 if (pCtx->hDec < 0) {
140 ALOGE("%s: Failed to open decoder device", __func__);
144 if (!exynos_v4l2_querycap(pCtx->hDec, needCaps)) {
145 ALOGE("%s: Failed to querycap", __func__);
146 goto EXIT_QUERYCAP_FAIL;
149 pCtx->bStreamonInbuf = VIDEO_FALSE;
150 pCtx->bStreamonOutbuf = VIDEO_FALSE;
152 pCtx->nMemoryType = nMemoryType;
154 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
155 if (pMutex == NULL) {
156 ALOGE("%s: Failed to allocate mutex about input buffer", __func__);
157 goto EXIT_QUERYCAP_FAIL;
159 if (pthread_mutex_init(pMutex, NULL) != 0) {
161 goto EXIT_QUERYCAP_FAIL;
163 pCtx->pInMutex = (void*)pMutex;
165 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
166 if (pMutex == NULL) {
167 ALOGE("%s: Failed to allocate mutex about output buffer", __func__);
168 goto EXIT_QUERYCAP_FAIL;
170 if (pthread_mutex_init(pMutex, NULL) != 0) {
172 goto EXIT_QUERYCAP_FAIL;
174 pCtx->pOutMutex = (void*)pMutex;
179 if (pCtx->pInMutex != NULL) {
180 pthread_mutex_destroy(pCtx->pInMutex);
181 free(pCtx->pInMutex);
184 if (pCtx->pOutMutex != NULL) {
185 pthread_mutex_destroy(pCtx->pOutMutex);
186 free(pCtx->pOutMutex);
199 * [Decoder OPS] Finalize
201 static ExynosVideoErrorType MFC_Decoder_Finalize(void *pHandle)
203 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
204 ExynosVideoPlane *pVideoPlane = NULL;
205 pthread_mutex_t *pMutex = NULL;
206 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
210 ALOGE("%s: Video context info must be supplied", __func__);
211 ret = VIDEO_ERROR_BADPARAM;
215 if (pCtx->pOutMutex != NULL) {
216 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
217 pthread_mutex_destroy(pMutex);
219 pCtx->pOutMutex = NULL;
222 if (pCtx->pInMutex != NULL) {
223 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
224 pthread_mutex_destroy(pMutex);
226 pCtx->pInMutex = NULL;
229 if (pCtx->bShareInbuf == VIDEO_FALSE) {
230 for (i = 0; i < pCtx->nInbufs; i++) {
231 for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) {
232 pVideoPlane = &pCtx->pInbuf[i].planes[j];
233 if (pVideoPlane->addr != NULL) {
234 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
235 pVideoPlane->addr = NULL;
236 pVideoPlane->allocSize = 0;
237 pVideoPlane->dataSize = 0;
240 pCtx->pInbuf[i].pGeometry = NULL;
241 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
242 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
247 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
248 for (i = 0; i < pCtx->nOutbufs; i++) {
249 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
250 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
251 if (pVideoPlane->addr != NULL) {
252 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
253 pVideoPlane->addr = NULL;
254 pVideoPlane->allocSize = 0;
255 pVideoPlane->dataSize = 0;
258 pCtx->pOutbuf[i].pGeometry = NULL;
259 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
260 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
265 if (pCtx->pInbuf != NULL)
268 if (pCtx->pOutbuf != NULL)
281 * [Decoder OPS] Set Frame Tag
283 static ExynosVideoErrorType MFC_Decoder_Set_FrameTag(
287 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
288 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
289 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
291 ALOGE("%s: Video context info must be supplied", __func__);
292 ret = VIDEO_ERROR_BADPARAM;
296 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) {
297 ret = VIDEO_ERROR_APIFAIL;
307 * [Decoder OPS] Get Frame Tag
309 static int MFC_Decoder_Get_FrameTag(void *pHandle)
311 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
315 ALOGE("%s: Video context info must be supplied", __func__);
318 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
319 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag);
326 * [Decoder OPS] Get Buffer Count
328 static int MFC_Decoder_Get_ActualBufferCount(void *pHandle)
330 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
331 int bufferCount = -1;
334 ALOGE("%s: Video context info must be supplied", __func__);
338 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, &bufferCount);
345 * [Decoder OPS] Set Display Delay
347 static ExynosVideoErrorType MFC_Decoder_Set_DisplayDelay(
351 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
352 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
355 ALOGE("%s: Video context info must be supplied", __func__);
356 ret = VIDEO_ERROR_BADPARAM;
360 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY, delay) != 0) {
361 ret = VIDEO_ERROR_APIFAIL;
369 * [Decoder OPS] Set Immediate Display
371 static ExynosVideoErrorType MFC_Decoder_Set_ImmediateDisplay( void *pHandle)
373 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
374 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
375 #ifdef V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY
377 ALOGE("%s: Video context info must be supplied", __func__);
378 ret = VIDEO_ERROR_BADPARAM;
382 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY, 1) != 0) {
383 ret = VIDEO_ERROR_APIFAIL;
391 * [Decoder OPS] Enable Packed PB
393 static ExynosVideoErrorType MFC_Decoder_Enable_PackedPB(void *pHandle)
395 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
396 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
399 ALOGE("%s: Video context info must be supplied", __func__);
400 ret = VIDEO_ERROR_BADPARAM;
403 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB
404 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB, 1) != 0) {
405 ret = VIDEO_ERROR_APIFAIL;
414 * [Decoder OPS] Enable Loop Filter
416 static ExynosVideoErrorType MFC_Decoder_Enable_LoopFilter(void *pHandle)
418 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
419 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
422 ALOGE("%s: Video context info must be supplied", __func__);
423 ret = VIDEO_ERROR_BADPARAM;
427 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 1) != 0) {
428 ret = VIDEO_ERROR_APIFAIL;
437 * [Decoder OPS] Enable Slice Mode
439 static ExynosVideoErrorType MFC_Decoder_Enable_SliceMode(void *pHandle)
441 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
442 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
445 ALOGE("%s: Video context info must be supplied", __func__);
446 ret = VIDEO_ERROR_BADPARAM;
450 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE, 1) != 0) {
451 ret = VIDEO_ERROR_APIFAIL;
460 * [Decoder OPS] Enable SEI Parsing
462 static ExynosVideoErrorType MFC_Decoder_Enable_SEIParsing(void *pHandle)
464 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
465 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
468 ALOGE("%s: Video context info must be supplied", __func__);
469 ret = VIDEO_ERROR_BADPARAM;
473 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING, 1) != 0) {
474 ret = VIDEO_ERROR_APIFAIL;
483 * [Decoder OPS] Get Frame Packing information
485 static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo(
487 ExynosVideoFramePacking *pFramePacking)
489 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
490 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
491 #ifdef V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL
492 struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM];
493 struct v4l2_ext_controls ext_ctrls;
495 int seiAvailable, seiInfo, seiGridPos, i;
496 unsigned int seiArgmtId;
499 if ((pCtx == NULL) || (pFramePacking == NULL)) {
500 ALOGE("%s: Video context info or FramePacking pointer must be supplied", __func__);
501 ret = VIDEO_ERROR_BADPARAM;
505 memset(pFramePacking, 0, sizeof(*pFramePacking));
506 memset(ext_ctrl, 0, (sizeof(struct v4l2_ext_control) * FRAME_PACK_SEI_INFO_NUM));
508 ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
509 ext_ctrls.count = FRAME_PACK_SEI_INFO_NUM;
510 ext_ctrls.controls = ext_ctrl;
511 ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL;
512 ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID;
513 ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO;
514 ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS;
516 if (exynos_v4l2_g_ext_ctrl(pCtx->hDec, &ext_ctrls) != 0) {
517 ret = VIDEO_ERROR_APIFAIL;
521 seiAvailable = ext_ctrl[0].value;
522 seiArgmtId = ext_ctrl[1].value;
523 seiInfo = ext_ctrl[2].value;
524 seiGridPos = ext_ctrl[3].value;
526 pFramePacking->available = seiAvailable;
527 pFramePacking->arrangement_id = seiArgmtId;
529 pFramePacking->arrangement_cancel_flag = OPERATE_BIT(seiInfo, 0x1, 0);
530 pFramePacking->arrangement_type = OPERATE_BIT(seiInfo, 0x3f, 1);
531 pFramePacking->quincunx_sampling_flag = OPERATE_BIT(seiInfo, 0x1, 8);
532 pFramePacking->content_interpretation_type = OPERATE_BIT(seiInfo, 0x3f, 9);
533 pFramePacking->spatial_flipping_flag = OPERATE_BIT(seiInfo, 0x1, 15);
534 pFramePacking->frame0_flipped_flag = OPERATE_BIT(seiInfo, 0x1, 16);
535 pFramePacking->field_views_flag = OPERATE_BIT(seiInfo, 0x1, 17);
536 pFramePacking->current_frame_is_frame0_flag = OPERATE_BIT(seiInfo, 0x1, 18);
538 pFramePacking->frame0_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 0);
539 pFramePacking->frame0_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 4);
540 pFramePacking->frame1_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 8);
541 pFramePacking->frame1_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 12);
549 * [Decoder OPS] Enable Decode waiting for share Mode,
550 * to make sure destination support is completed and
551 * reset when Destination streamoff
553 static ExynosVideoErrorType MFC_Decoder_Enable_DecodeWait(void *pHandle)
555 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
556 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
557 #ifdef V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START
559 ALOGE("%s: Video context info must be supplied", __func__);
560 ret = VIDEO_ERROR_BADPARAM;
564 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START, 1) != 0) {
565 ret = VIDEO_ERROR_APIFAIL;
576 * [Decoder Buffer OPS] Enable Cacheable (Input)
578 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Inbuf(void *pHandle)
580 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
581 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
584 ALOGE("%s: Video context info must be supplied", __func__);
585 ret = VIDEO_ERROR_BADPARAM;
588 #ifdef V4L2_CID_CACHEABLE
589 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 2) != 0) {
590 ret = VIDEO_ERROR_APIFAIL;
599 * [Decoder Buffer OPS] Enable Cacheable (Output)
601 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Outbuf(void *pHandle)
603 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
604 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
607 ALOGE("%s: Video context info must be supplied", __func__);
608 ret = VIDEO_ERROR_BADPARAM;
611 #ifdef V4L2_CID_CACHEABLE
612 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 1) != 0) {
613 ret = VIDEO_ERROR_APIFAIL;
622 * [Decoder Buffer OPS] Set Shareable Buffer (Input)
624 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Inbuf(void *pHandle)
626 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
627 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
630 ALOGE("%s: Video context info must be supplied", __func__);
631 ret = VIDEO_ERROR_BADPARAM;
635 pCtx->bShareInbuf = VIDEO_TRUE;
642 * [Decoder Buffer OPS] Set Shareable Buffer (Output)
644 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Outbuf(void *pHandle)
646 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
647 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
650 ALOGE("%s: Video context info must be supplied", __func__);
651 ret = VIDEO_ERROR_BADPARAM;
655 pCtx->bShareOutbuf = VIDEO_TRUE;
662 * [Decoder Buffer OPS] Get Buffer (Input)
664 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Inbuf(
667 ExynosVideoBuffer **pBuffer)
669 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
670 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
673 ALOGE("%s: Video context info must be supplied", __func__);
675 ret = VIDEO_ERROR_BADPARAM;
679 if (pCtx->nInbufs <= nIndex) {
681 ret = VIDEO_ERROR_BADPARAM;
685 *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex];
692 * [Decoder Buffer OPS] Get Buffer (Output)
694 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Outbuf(
697 ExynosVideoBuffer **pBuffer)
699 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
700 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
703 ALOGE("%s: Video context info must be supplied", __func__);
705 ret = VIDEO_ERROR_BADPARAM;
709 if (pCtx->nOutbufs <= nIndex) {
711 ret = VIDEO_ERROR_BADPARAM;
715 *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex];
722 * [Decoder Buffer OPS] Set Geometry (Input)
724 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Inbuf(
726 ExynosVideoGeometry *bufferConf)
728 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
729 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
731 struct v4l2_format fmt;
734 ALOGE("%s: Video context info must be supplied", __func__);
735 ret = VIDEO_ERROR_BADPARAM;
739 if (bufferConf == NULL) {
740 ALOGE("%s: Buffer geometry must be supplied", __func__);
741 ret = VIDEO_ERROR_BADPARAM;
745 memset(&fmt, 0, sizeof(fmt));
747 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
748 fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat);
749 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage;
751 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) {
752 ret = VIDEO_ERROR_APIFAIL;
756 memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry));
763 * [Decoder Buffer OPS] Set Geometry (Output)
765 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Outbuf(
767 ExynosVideoGeometry *bufferConf)
769 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
770 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
772 struct v4l2_format fmt;
775 ALOGE("%s: Video context info must be supplied", __func__);
776 ret = VIDEO_ERROR_BADPARAM;
780 if (bufferConf == NULL) {
781 ALOGE("%s: Buffer geometry must be supplied", __func__);
782 ret = VIDEO_ERROR_BADPARAM;
786 memset(&fmt, 0, sizeof(fmt));
788 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
789 fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat);
791 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) {
792 ret = VIDEO_ERROR_APIFAIL;
796 memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry));
803 * [Decoder Buffer OPS] Get Geometry (Output)
805 static ExynosVideoErrorType MFC_Decoder_Get_Geometry_Outbuf(
807 ExynosVideoGeometry *bufferConf)
809 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
810 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
812 struct v4l2_format fmt;
813 struct v4l2_crop crop;
816 ALOGE("%s: Video context info must be supplied", __func__);
817 ret = VIDEO_ERROR_BADPARAM;
821 if (bufferConf == NULL) {
822 ALOGE("%s: Buffer geometry must be supplied", __func__);
823 ret = VIDEO_ERROR_BADPARAM;
827 memset(&fmt, 0, sizeof(fmt));
828 memset(&crop, 0, sizeof(crop));
830 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
832 if (exynos_v4l2_g_fmt(pCtx->hDec, &fmt) != 0) {
833 ALOGE("%s: exynos_v4l2_g_fmt. ret = %d", __func__, ret);
834 ret = VIDEO_ERROR_APIFAIL;
838 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
840 if (exynos_v4l2_g_crop(pCtx->hDec, &crop) != 0) {
841 ALOGE("%s: exynos_v4l2_g_crop. ret=%d", __func__, ret);
842 ret = VIDEO_ERROR_APIFAIL;
846 bufferConf->nFrameWidth = fmt.fmt.pix_mp.width;
847 bufferConf->nFrameHeight = fmt.fmt.pix_mp.height;
849 bufferConf->cropRect.nTop = crop.c.top;
850 bufferConf->cropRect.nLeft = crop.c.left;
851 bufferConf->cropRect.nWidth = crop.c.width;
852 bufferConf->cropRect.nHeight = crop.c.height;
859 * [Decoder Buffer OPS] Setup (Input)
861 static ExynosVideoErrorType MFC_Decoder_Setup_Inbuf(
863 unsigned int nBufferCount)
865 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
866 ExynosVideoPlane *pVideoPlane = NULL;
867 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
869 struct v4l2_requestbuffers req;
870 struct v4l2_buffer buf;
871 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES];
875 ALOGE("%s: Video context info must be supplied", __func__);
876 ret = VIDEO_ERROR_BADPARAM;
880 if (nBufferCount == 0) {
881 ALOGE("%s: Buffer count must be greater than 0", __func__);
882 ret = VIDEO_ERROR_BADPARAM;
886 ALOGV("%s: setting up inbufs (%d) shared=%s\n", __func__, nBufferCount,
887 pCtx->bShareInbuf ? "true" : "false");
889 memset(&req, 0, sizeof(req));
891 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
892 req.count = nBufferCount;
894 if (pCtx->bShareInbuf == VIDEO_TRUE)
895 req.memory = pCtx->nMemoryType;
897 req.memory = V4L2_MEMORY_MMAP;
899 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
900 ret = VIDEO_ERROR_APIFAIL;
904 if (req.count != nBufferCount) {
905 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count);
906 ret = VIDEO_ERROR_NOMEM;
910 pCtx->nInbufs = (int)req.count;
912 pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
913 if (pCtx->pInbuf == NULL) {
914 ALOGE("Failed to allocate input buffer context");
915 ret = VIDEO_ERROR_NOMEM;
918 memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
920 memset(&buf, 0, sizeof(buf));
922 if (pCtx->bShareInbuf == VIDEO_FALSE) {
923 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
924 buf.memory = V4L2_MEMORY_MMAP;
925 buf.m.planes = planes;
926 buf.length = VIDEO_DECODER_INBUF_PLANES;
928 ALOGV("[%s] INBUF V4L2_MEMORY_MMAP", __func__);
929 for (i = 0; i < pCtx->nInbufs; i++) {
931 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) {
932 ret = VIDEO_ERROR_APIFAIL;
936 pVideoPlane = &pCtx->pInbuf[i].planes[0];
938 pVideoPlane->addr = mmap(NULL,
939 buf.m.planes[0].length, PROT_READ | PROT_WRITE,
940 MAP_SHARED, pCtx->hDec, buf.m.planes[0].m.mem_offset);
942 if (pVideoPlane->addr == MAP_FAILED) {
943 ret = VIDEO_ERROR_MAPFAIL;
947 pVideoPlane->allocSize = buf.m.planes[0].length;
948 pVideoPlane->dataSize = 0;
950 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
951 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
952 pCtx->pInbuf[i].bRegistered = VIDEO_TRUE;
959 if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) {
960 if (pCtx->bShareInbuf == VIDEO_FALSE) {
961 for (i = 0; i < pCtx->nInbufs; i++) {
962 pVideoPlane = &pCtx->pInbuf[i].planes[0];
963 if (pVideoPlane->addr == MAP_FAILED) {
964 pVideoPlane->addr = NULL;
968 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
979 * [Decoder Buffer OPS] Setup (Output)
981 static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf(
983 unsigned int nBufferCount)
985 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
986 ExynosVideoPlane *pVideoPlane = NULL;
987 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
989 struct v4l2_requestbuffers req;
990 struct v4l2_buffer buf;
991 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES];
995 ALOGE("%s: Video context info must be supplied", __func__);
996 ret = VIDEO_ERROR_BADPARAM;
1000 if (nBufferCount == 0) {
1001 ALOGE("%s: Buffer count must be greater than 0", __func__);
1002 ret = VIDEO_ERROR_BADPARAM;
1006 ALOGV("%s: setting up outbufs (%d) shared=%s\n", __func__, nBufferCount,
1007 pCtx->bShareOutbuf ? "true" : "false");
1009 memset(&req, 0, sizeof(req));
1011 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1012 req.count = nBufferCount;
1014 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1015 req.memory = pCtx->nMemoryType;
1017 req.memory = V4L2_MEMORY_MMAP;
1019 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1020 ret = VIDEO_ERROR_APIFAIL;
1024 if (req.count != nBufferCount) {
1025 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count);
1026 ret = VIDEO_ERROR_NOMEM;
1030 pCtx->nOutbufs = req.count;
1032 pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1033 if (pCtx->pOutbuf == NULL) {
1034 ALOGE("Failed to allocate output buffer context");
1035 ret = VIDEO_ERROR_NOMEM;
1038 memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1040 memset(&buf, 0, sizeof(buf));
1042 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1043 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1044 buf.memory = V4L2_MEMORY_MMAP;
1045 buf.m.planes = planes;
1046 buf.length = VIDEO_DECODER_OUTBUF_PLANES;
1048 ALOGV("[%s] OUTBUF V4L2_MEMORY_MMAP", __func__);
1049 for (i = 0; i < pCtx->nOutbufs; i++) {
1051 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) {
1052 ret = VIDEO_ERROR_APIFAIL;
1056 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1057 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1058 pVideoPlane->addr = mmap(NULL,
1059 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1060 MAP_SHARED, pCtx->hDec, buf.m.planes[j].m.mem_offset);
1062 if (pVideoPlane->addr == MAP_FAILED) {
1063 ret = VIDEO_ERROR_MAPFAIL;
1067 pVideoPlane->allocSize = buf.m.planes[j].length;
1068 pVideoPlane->dataSize = 0;
1070 #ifdef TIZEN_FEATURE_E3250 /* dmabuf */
1072 if (pCtx->bufShareMethod == BUF_SHARE_FD) {
1073 exynos_v4l2_expbuf(pCtx->hDec, &pVideoPlane->fd, buf.m.planes[j].m.mem_offset);
1074 ALOGV("[%s] fd (%d) received from MFC", __func__, pVideoPlane->fd);
1080 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1081 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1082 pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE;
1089 if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) {
1090 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1091 for (i = 0; i < pCtx->nOutbufs; i++) {
1092 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1093 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1094 if (pVideoPlane->addr == MAP_FAILED) {
1095 pVideoPlane->addr = NULL;
1099 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1104 free(pCtx->pOutbuf);
1111 * [Decoder Buffer OPS] Run (Input)
1113 static ExynosVideoErrorType MFC_Decoder_Run_Inbuf(void *pHandle)
1115 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1116 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1119 ALOGE("%s: Video context info must be supplied", __func__);
1120 ret = VIDEO_ERROR_BADPARAM;
1124 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1125 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1126 ALOGE("%s: Failed to streamon for input buffer", __func__);
1127 ret = VIDEO_ERROR_APIFAIL;
1130 pCtx->bStreamonInbuf = VIDEO_TRUE;
1138 * [Decoder Buffer OPS] Run (Output)
1140 static ExynosVideoErrorType MFC_Decoder_Run_Outbuf(void *pHandle)
1142 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1143 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1146 ALOGE("%s: Video context info must be supplied", __func__);
1147 ret = VIDEO_ERROR_BADPARAM;
1151 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1152 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1153 ALOGE("%s: Failed to streamon for output buffer", __func__);
1154 ret = VIDEO_ERROR_APIFAIL;
1157 pCtx->bStreamonOutbuf = VIDEO_TRUE;
1165 * [Decoder Buffer OPS] Stop (Input)
1167 static ExynosVideoErrorType MFC_Decoder_Stop_Inbuf(void *pHandle)
1169 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1170 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1174 ALOGE("%s: Video context info must be supplied", __func__);
1175 ret = VIDEO_ERROR_BADPARAM;
1179 if (pCtx->bStreamonInbuf == VIDEO_TRUE) {
1180 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1181 ALOGE("%s: Failed to streamoff for input buffer", __func__);
1182 ret = VIDEO_ERROR_APIFAIL;
1185 pCtx->bStreamonInbuf = VIDEO_FALSE;
1188 for (i = 0; i < pCtx->nInbufs; i++) {
1189 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1197 * [Decoder Buffer OPS] Stop (Output)
1199 static ExynosVideoErrorType MFC_Decoder_Stop_Outbuf(void *pHandle)
1201 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1202 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1206 ALOGE("%s: Video context info must be supplied", __func__);
1207 ret = VIDEO_ERROR_BADPARAM;
1211 if (pCtx->bStreamonOutbuf == VIDEO_TRUE) {
1212 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1213 ALOGE("%s: Failed to streamoff for output buffer", __func__);
1214 ret = VIDEO_ERROR_APIFAIL;
1217 pCtx->bStreamonOutbuf = VIDEO_FALSE;
1220 for (i = 0; i < pCtx->nOutbufs; i++) {
1221 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1229 * [Decoder Buffer OPS] Wait (Input)
1231 static ExynosVideoErrorType MFC_Decoder_Wait_Inbuf(void *pHandle)
1233 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1234 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1236 struct pollfd poll_events;
1240 ALOGE("%s: Video context info must be supplied", __func__);
1241 ret = VIDEO_ERROR_BADPARAM;
1245 poll_events.fd = pCtx->hDec;
1246 poll_events.events = POLLOUT | POLLERR;
1247 poll_events.revents = 0;
1250 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_DECODER_POLL_TIMEOUT);
1251 if (poll_state > 0) {
1252 if (poll_events.revents & POLLOUT) {
1255 ALOGE("%s: Poll return error", __func__);
1256 ret = VIDEO_ERROR_POLL;
1259 } else if (poll_state < 0) {
1260 ALOGE("%s: Poll state error", __func__);
1261 ret = VIDEO_ERROR_POLL;
1264 } while (poll_state == 0);
1270 static ExynosVideoErrorType MFC_Decoder_Register_Inbuf(
1272 ExynosVideoPlane *planes,
1275 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1276 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1279 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_INBUF_PLANES)) {
1280 ALOGE("%s: params must be supplied", __func__);
1281 ret = VIDEO_ERROR_BADPARAM;
1285 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1286 if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) {
1287 for (plane = 0; plane < nPlanes; plane++) {
1288 pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr;
1289 pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1290 pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd;
1291 ALOGV("%s: registered buf %d (addr=%p alloc_sz=%ld fd=%d)\n", __func__, nIndex,
1292 planes[plane].addr, planes[plane].allocSize, planes[plane].fd);
1294 pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE;
1299 if (nIndex == pCtx->nInbufs) {
1300 ALOGE("%s: can not find non-registered input buffer", __func__);
1301 ret = VIDEO_ERROR_NOBUFFERS;
1308 static ExynosVideoErrorType MFC_Decoder_Register_Outbuf(
1310 ExynosVideoPlane *planes,
1313 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1314 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1317 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_OUTBUF_PLANES)) {
1318 ALOGE("%s: params must be supplied", __func__);
1319 ret = VIDEO_ERROR_BADPARAM;
1323 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1324 if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) {
1325 for (plane = 0; plane < nPlanes; plane++) {
1326 pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr;
1327 pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1328 pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd;
1329 pCtx->pOutbuf[nIndex].planes[plane].tbm_bo = planes[plane].tbm_bo;
1331 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE;
1332 ALOGV("%s: registered buf %d 0:(addr=%p alloc_sz=%d fd=%d) 1:(addr=%p alloc_sz=%d fd=%d)\n",
1333 __func__, nIndex, planes[0].addr, planes[0].allocSize, planes[0].fd,
1334 planes[1].addr, planes[1].allocSize, planes[1].fd);
1339 if (nIndex == pCtx->nOutbufs) {
1340 ALOGE("%s: can not find non-registered output buffer", __func__);
1341 ret = VIDEO_ERROR_NOBUFFERS;
1348 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
1350 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1351 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1355 ALOGE("%s: Video context info must be supplied", __func__);
1356 ret = VIDEO_ERROR_BADPARAM;
1360 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1361 pCtx->pInbuf[nIndex].planes[0].addr = NULL;
1362 pCtx->pInbuf[nIndex].planes[0].fd = -1;
1363 pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE;
1370 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
1372 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1373 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1377 ALOGE("%s: Video context info must be supplied", __func__);
1378 ret = VIDEO_ERROR_BADPARAM;
1382 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1383 pCtx->pOutbuf[nIndex].planes[0].addr = NULL;
1384 pCtx->pOutbuf[nIndex].planes[0].fd = -1;
1385 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE;
1393 * [Decoder Buffer OPS] Find (Input)
1395 static int MFC_Decoder_Find_Inbuf(
1397 unsigned char *pBuffer)
1399 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1403 ALOGE("%s: Video context info must be supplied", __func__);
1407 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1408 if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) {
1409 if ((pBuffer == NULL) ||
1410 (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer))
1415 if (nIndex == pCtx->nInbufs)
1423 * [Decoder Buffer OPS] Find (Outnput)
1425 static int MFC_Decoder_Find_Outbuf(
1427 unsigned char *pBuffer)
1429 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1433 ALOGE("%s: Video context info must be supplied", __func__);
1437 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1438 if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) {
1439 if ((pBuffer == NULL) ||
1440 (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer))
1445 if (nIndex == pCtx->nOutbufs)
1453 * [Decoder Buffer OPS] Enqueue (Input)
1455 static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf(
1457 unsigned char *pBuffer[],
1458 unsigned int dataSize[],
1462 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1463 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1464 pthread_mutex_t *pMutex = NULL;
1466 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES];
1467 struct v4l2_buffer buf;
1471 ALOGE("%s: Video context info must be supplied", __func__);
1472 ret = VIDEO_ERROR_BADPARAM;
1476 if (VIDEO_DECODER_INBUF_PLANES < nPlanes) {
1477 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1478 VIDEO_DECODER_INBUF_PLANES, nPlanes);
1479 ret = VIDEO_ERROR_BADPARAM;
1483 memset(&buf, 0, sizeof(buf));
1485 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1486 buf.m.planes = planes;
1487 buf.length = VIDEO_DECODER_INBUF_PLANES;
1489 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
1490 pthread_mutex_lock(pMutex);
1491 index = MFC_Decoder_Find_Inbuf(pCtx, pBuffer[0]);
1493 pthread_mutex_unlock(pMutex);
1494 ALOGE("%s: Failed to get index", __func__);
1495 ret = VIDEO_ERROR_NOBUFFERS;
1500 pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE;
1501 pthread_mutex_unlock(pMutex);
1503 if (pCtx->bShareInbuf == VIDEO_TRUE) {
1504 buf.memory = pCtx->nMemoryType;
1505 for (i = 0; i < nPlanes; i++) {
1506 /* V4L2_MEMORY_USERPTR */
1507 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1508 /* V4L2_MEMORY_DMABUF */
1510 buf.m.planes[i].m.fd = pCtx->pInbuf[index].planes[i].fd;
1512 buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize;
1513 buf.m.planes[i].bytesused = dataSize[i];
1514 ALOGV("%s: shared INBUF(%d) plane(%d) data_offset= %x addr=%p len=%d used=%d\n", __func__,
1516 buf.m.planes[i].data_offset,
1517 buf.m.planes[i].m.userptr,
1518 buf.m.planes[i].length,
1519 buf.m.planes[i].bytesused);
1522 buf.memory = V4L2_MEMORY_MMAP;
1523 for (i = 0; i < nPlanes; i++)
1524 buf.m.planes[i].bytesused = dataSize[i];
1527 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) {
1528 ALOGE("%s: Failed to enqueue input buffer", __func__);
1529 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1530 ret = VIDEO_ERROR_APIFAIL;
1534 pCtx->pInbuf[buf.index].pPrivate = pPrivate;
1541 * [Decoder Buffer OPS] Enqueue (Output)
1543 static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf(
1545 unsigned char *pBuffer[],
1546 unsigned int dataSize[],
1550 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1551 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1552 pthread_mutex_t *pMutex = NULL;
1554 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES];
1555 struct v4l2_buffer buf;
1559 ALOGE("%s: Video context info must be supplied", __func__);
1560 ret = VIDEO_ERROR_BADPARAM;
1564 if (VIDEO_DECODER_OUTBUF_PLANES < nPlanes) {
1565 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1566 VIDEO_DECODER_OUTBUF_PLANES, nPlanes);
1567 ret = VIDEO_ERROR_BADPARAM;
1571 memset(&buf, 0, sizeof(buf));
1573 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1574 buf.m.planes = planes;
1575 buf.length = VIDEO_DECODER_OUTBUF_PLANES;
1577 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
1578 pthread_mutex_lock(pMutex);
1579 index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]);
1581 pthread_mutex_unlock(pMutex);
1582 ALOGE("%s: Failed to get index", __func__);
1583 ret = VIDEO_ERROR_NOBUFFERS;
1587 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE;
1588 pthread_mutex_unlock(pMutex);
1590 if (pCtx->bShareOutbuf == VIDEO_TRUE) {
1591 buf.memory = pCtx->nMemoryType;
1592 for (i = 0; i < nPlanes; i++) {
1593 /* V4L2_MEMORY_USERPTR */
1594 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1595 /* V4L2_MEMORY_DMABUF */
1597 buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd;
1599 buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize;
1600 buf.m.planes[i].bytesused = dataSize[i];
1601 ALOGV("%s: shared OUTBUF(%d) plane=%d data_offset= %x addr=0x%lx len=%d used=%d\n", __func__,
1603 buf.m.planes[i].data_offset,
1604 buf.m.planes[i].m.userptr,
1605 buf.m.planes[i].length,
1606 buf.m.planes[i].bytesused);
1609 ALOGV("%s: non-shared outbuf(%d)\n", __func__, index);
1610 buf.memory = V4L2_MEMORY_MMAP;
1613 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) {
1614 ALOGE("%s: Failed to enqueue output buffer", __func__);
1615 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE;
1616 ret = VIDEO_ERROR_APIFAIL;
1620 pCtx->pOutbuf[buf.index].pPrivate = pPrivate;
1627 * [Decoder Buffer OPS] Dequeue (Input)
1629 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle)
1631 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1632 ExynosVideoBuffer *pInbuf = NULL;
1634 struct v4l2_buffer buf;
1637 ALOGE("%s: Video context info must be supplied", __func__);
1641 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1646 memset(&buf, 0, sizeof(buf));
1648 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1650 if (pCtx->bShareInbuf == VIDEO_TRUE)
1651 buf.memory = pCtx->nMemoryType;
1653 buf.memory = V4L2_MEMORY_MMAP;
1655 if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) {
1660 pInbuf = &pCtx->pInbuf[buf.index];
1661 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1663 if (pCtx->bStreamonInbuf == VIDEO_FALSE)
1671 * [Decoder Buffer OPS] Dequeue (Output)
1673 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle)
1675 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1676 ExynosVideoBuffer *pOutbuf = NULL;
1678 struct v4l2_buffer buf;
1684 ALOGE("%s: Video context info must be supplied", __func__);
1688 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1693 memset(&buf, 0, sizeof(buf));
1694 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1696 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1697 buf.memory = pCtx->nMemoryType;
1699 buf.memory = V4L2_MEMORY_MMAP;
1701 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
1702 ret = exynos_v4l2_dqbuf(pCtx->hDec, &buf);
1705 pOutbuf = (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO;
1711 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1716 pOutbuf = &pCtx->pOutbuf[buf.index];
1718 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS
1719 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value);
1721 ALOGV("%s: V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS value = %d", __func__, value);
1724 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY;
1727 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING;
1730 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY;
1733 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state);
1734 if (state == 1) /* Resolution change is detected */
1735 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
1736 else /* Decoding is finished */
1737 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED;
1740 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1744 switch (buf.flags & (0x7 << 3)) {
1745 ALOGV("%s: frameType: %d", __func__, buf.flags & (0x7 << 3));
1746 case V4L2_BUF_FLAG_KEYFRAME:
1747 pOutbuf->frameType = VIDEO_FRAME_I;
1749 case V4L2_BUF_FLAG_PFRAME:
1750 pOutbuf->frameType = VIDEO_FRAME_P;
1752 case V4L2_BUF_FLAG_BFRAME:
1753 pOutbuf->frameType = VIDEO_FRAME_B;
1756 pOutbuf->frameType = VIDEO_FRAME_OTHERS;
1760 pOutbuf->bQueued = VIDEO_FALSE;
1766 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Inbuf(void *pHandle)
1768 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1769 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1773 ALOGE("%s: Video context info must be supplied", __func__);
1774 ret = VIDEO_ERROR_BADPARAM;
1778 for (i = 0; i < pCtx->nInbufs; i++) {
1779 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1786 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Outbuf(void *pHandle)
1788 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1789 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1793 ALOGE("%s: Video context info must be supplied", __func__);
1794 ret = VIDEO_ERROR_BADPARAM;
1798 for (i = 0; i < pCtx->nOutbufs; i++) {
1799 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1806 /* [Decoder Buffer OPS] Cleanup (Input)
1808 static ExynosVideoErrorType MFC_Decoder_Cleanup_Inbuf(void *pHandle)
1810 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1811 ExynosVideoPlane *pVideoPlane = NULL;
1812 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1814 struct v4l2_requestbuffers req;
1815 int nBufferCount, i, j;
1818 ALOGE("%s: Video context info must be supplied", __func__);
1819 ret = VIDEO_ERROR_BADPARAM;
1823 nBufferCount = 0; /* for Clean-up */
1825 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1826 for (i = 0; i < pCtx->nInbufs; i++) {
1827 for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) {
1828 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1829 if (pVideoPlane->addr != NULL) {
1830 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1831 pVideoPlane->addr = NULL;
1832 pVideoPlane->allocSize = 0;
1833 pVideoPlane->dataSize = 0;
1836 pCtx->pInbuf[i].pGeometry = NULL;
1837 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1838 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
1843 memset(&req, 0, sizeof(req));
1845 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1846 req.count = nBufferCount;
1848 if (pCtx->bShareInbuf == VIDEO_TRUE)
1849 req.memory = pCtx->nMemoryType;
1851 req.memory = V4L2_MEMORY_MMAP;
1853 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1854 ret = VIDEO_ERROR_APIFAIL;
1858 pCtx->nInbufs = (int)req.count;
1860 if (pCtx->pInbuf != NULL)
1868 * [Decoder Buffer OPS] Cleanup (Output)
1870 static ExynosVideoErrorType MFC_Decoder_Cleanup_Outbuf(void *pHandle)
1872 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1873 ExynosVideoPlane *pVideoPlane = NULL;
1874 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1876 struct v4l2_requestbuffers req;
1877 int nBufferCount, i ,j;
1880 ALOGE("%s: Video context info must be supplied", __func__);
1881 ret = VIDEO_ERROR_BADPARAM;
1885 nBufferCount = 0; /* for Clean-up */
1887 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1888 for (i = 0; i < pCtx->nOutbufs; i++) {
1889 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1890 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1891 if (pVideoPlane->addr != NULL) {
1892 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1893 pVideoPlane->addr = NULL;
1894 pVideoPlane->allocSize = 0;
1895 pVideoPlane->dataSize = 0;
1898 pCtx->pOutbuf[i].pGeometry = NULL;
1899 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1900 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
1905 memset(&req, 0, sizeof(req));
1907 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1908 req.count = nBufferCount;
1910 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1911 req.memory = pCtx->nMemoryType;
1913 req.memory = V4L2_MEMORY_MMAP;
1915 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1916 ALOGE("reqbuf fail");
1917 ret = VIDEO_ERROR_APIFAIL;
1921 pCtx->nOutbufs = req.count;
1923 if (pCtx->pOutbuf != NULL)
1924 free(pCtx->pOutbuf);
1931 * [Decoder OPS] Common
1933 static ExynosVideoDecOps defDecOps = {
1935 .Init = MFC_Decoder_Init,
1936 .Finalize = MFC_Decoder_Finalize,
1937 .Set_DisplayDelay = MFC_Decoder_Set_DisplayDelay,
1938 .Enable_PackedPB = MFC_Decoder_Enable_PackedPB,
1939 .Enable_LoopFilter = MFC_Decoder_Enable_LoopFilter,
1940 .Enable_SliceMode = MFC_Decoder_Enable_SliceMode,
1941 .Get_ActualBufferCount = MFC_Decoder_Get_ActualBufferCount,
1942 .Set_FrameTag = MFC_Decoder_Set_FrameTag,
1943 .Get_FrameTag = MFC_Decoder_Get_FrameTag,
1944 .Enable_SEIParsing = MFC_Decoder_Enable_SEIParsing,
1945 .Get_FramePackingInfo = MFC_Decoder_Get_FramePackingInfo,
1946 .Set_ImmediateDisplay = MFC_Decoder_Set_ImmediateDisplay,
1947 .Enable_DecodeWait = MFC_Decoder_Enable_DecodeWait,
1951 * [Decoder Buffer OPS] Input
1953 static ExynosVideoDecBufferOps defInbufOps = {
1955 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Inbuf,
1956 .Set_Shareable = MFC_Decoder_Set_Shareable_Inbuf,
1957 .Get_Buffer = MFC_Decoder_Get_Buffer_Inbuf,
1958 .Set_Geometry = MFC_Decoder_Set_Geometry_Inbuf,
1959 .Get_Geometry = NULL,
1960 .Setup = MFC_Decoder_Setup_Inbuf,
1961 .Run = MFC_Decoder_Run_Inbuf,
1962 .Stop = MFC_Decoder_Stop_Inbuf,
1963 .Enqueue = MFC_Decoder_Enqueue_Inbuf,
1964 .Enqueue_All = NULL,
1965 .Dequeue = MFC_Decoder_Dequeue_Inbuf,
1966 .Register = MFC_Decoder_Register_Inbuf,
1967 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Inbuf,
1968 .Clear_Queue = MFC_Decoder_Clear_Queued_Inbuf,
1969 .Cleanup = MFC_Decoder_Cleanup_Inbuf,
1973 * [Decoder Buffer OPS] Output
1975 static ExynosVideoDecBufferOps defOutbufOps = {
1977 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Outbuf,
1978 .Set_Shareable = MFC_Decoder_Set_Shareable_Outbuf,
1979 .Get_Buffer = MFC_Decoder_Get_Buffer_Outbuf,
1980 .Set_Geometry = MFC_Decoder_Set_Geometry_Outbuf,
1981 .Get_Geometry = MFC_Decoder_Get_Geometry_Outbuf,
1982 .Setup = MFC_Decoder_Setup_Outbuf,
1983 .Run = MFC_Decoder_Run_Outbuf,
1984 .Stop = MFC_Decoder_Stop_Outbuf,
1985 .Enqueue = MFC_Decoder_Enqueue_Outbuf,
1986 .Enqueue_All = NULL,
1987 .Dequeue = MFC_Decoder_Dequeue_Outbuf,
1988 .Register = MFC_Decoder_Register_Outbuf,
1989 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Outbuf,
1990 .Clear_Queue = MFC_Decoder_Clear_Queued_Outbuf,
1991 .Cleanup = MFC_Decoder_Cleanup_Outbuf,
1994 int Exynos_Video_Register_Decoder(
1995 ExynosVideoDecOps *pDecOps,
1996 ExynosVideoDecBufferOps *pInbufOps,
1997 ExynosVideoDecBufferOps *pOutbufOps)
1999 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2001 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
2002 ret = VIDEO_ERROR_BADPARAM;
2006 defDecOps.nSize = sizeof(defDecOps);
2007 defInbufOps.nSize = sizeof(defInbufOps);
2008 defOutbufOps.nSize = sizeof(defOutbufOps);
2010 memcpy((char *)pDecOps + sizeof(pDecOps->nSize), (char *)&defDecOps + sizeof(defDecOps.nSize),
2011 pDecOps->nSize - sizeof(pDecOps->nSize));
2013 memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
2014 pInbufOps->nSize - sizeof(pInbufOps->nSize));
2016 memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
2017 pOutbufOps->nSize - sizeof(pOutbufOps->nSize));