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 #include <mm_ta/mm_ta.h>
47 /* #define LOG_NDEBUG 0 */
48 #define LOG_TAG "ExynosVideoDecoder"
49 #ifndef SLP_PLATFORM /* build env */
50 #include <utils/Log.h>
52 #include "Exynos_OSAL_Log.h"
56 * [Common] __CodingType_To_V4L2PixelFormat
58 static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType)
60 unsigned int pixelformat = V4L2_PIX_FMT_H264;
63 case VIDEO_CODING_AVC:
64 pixelformat = V4L2_PIX_FMT_H264;
66 case VIDEO_CODING_MPEG4:
67 pixelformat = V4L2_PIX_FMT_MPEG4;
69 case VIDEO_CODING_VP8:
70 pixelformat = V4L2_PIX_FMT_VP8;
72 case VIDEO_CODING_H263:
73 pixelformat = V4L2_PIX_FMT_H263;
75 case VIDEO_CODING_VC1:
76 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G;
78 case VIDEO_CODING_VC1_RCV:
79 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L;
81 case VIDEO_CODING_MPEG2:
82 pixelformat = V4L2_PIX_FMT_MPEG2;
85 pixelformat = V4L2_PIX_FMT_H264;
93 * [Common] __ColorFormatType_To_V4L2PixelFormat
95 static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType)
97 unsigned int pixelformat = V4L2_PIX_FMT_NV12M;
99 switch (colorFormatType) {
100 case VIDEO_COLORFORMAT_NV12_TILED:
102 pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
104 pixelformat = V4L2_PIX_FMT_NV12MT;
108 case VIDEO_COLORFORMAT_NV21:
109 pixelformat = V4L2_PIX_FMT_NV21M;
111 case VIDEO_COLORFORMAT_NV12:
113 pixelformat = V4L2_PIX_FMT_NV12M;
124 static void *MFC_Decoder_Init(int nMemoryType)
126 ExynosVideoDecContext *pCtx = NULL;
127 pthread_mutex_t *pMutex = NULL;
128 int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING);
130 MMTA_ACUM_ITEM_BEGIN("Video First Frame Coming", 0);
132 pCtx = (ExynosVideoDecContext *)malloc(sizeof(*pCtx));
134 ALOGE("%s: Failed to allocate decoder context buffer", __func__);
135 goto EXIT_ALLOC_FAIL;
138 memset(pCtx, 0, sizeof(*pCtx));
140 __ta__("exynos_v4l2_open_devname : VIDEO_DECODER_NAME",
141 pCtx->hDec = exynos_v4l2_open_devname(VIDEO_DECODER_NAME, O_RDWR, 0);
143 if (pCtx->hDec < 0) {
144 ALOGE("%s: Failed to open decoder device", __func__);
148 __ta__("exynos_v4l2_querycap",
149 if (!exynos_v4l2_querycap(pCtx->hDec, needCaps)) {
150 ALOGE("%s: Failed to querycap", __func__);
151 goto EXIT_QUERYCAP_FAIL;
155 pCtx->bStreamonInbuf = VIDEO_FALSE;
156 pCtx->bStreamonOutbuf = VIDEO_FALSE;
158 pCtx->nMemoryType = nMemoryType;
160 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
161 if (pMutex == NULL) {
162 ALOGE("%s: Failed to allocate mutex about input buffer", __func__);
163 goto EXIT_QUERYCAP_FAIL;
165 if (pthread_mutex_init(pMutex, NULL) != 0) {
167 goto EXIT_QUERYCAP_FAIL;
169 pCtx->pInMutex = (void*)pMutex;
171 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
172 if (pMutex == NULL) {
173 ALOGE("%s: Failed to allocate mutex about output buffer", __func__);
174 goto EXIT_QUERYCAP_FAIL;
176 if (pthread_mutex_init(pMutex, NULL) != 0) {
178 goto EXIT_QUERYCAP_FAIL;
180 pCtx->pOutMutex = (void*)pMutex;
185 if (pCtx->pInMutex != NULL) {
186 pthread_mutex_destroy(pCtx->pInMutex);
187 free(pCtx->pInMutex);
190 if (pCtx->pOutMutex != NULL) {
191 pthread_mutex_destroy(pCtx->pOutMutex);
192 free(pCtx->pOutMutex);
205 * [Decoder OPS] Finalize
207 static ExynosVideoErrorType MFC_Decoder_Finalize(void *pHandle)
209 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
210 ExynosVideoPlane *pVideoPlane = NULL;
211 pthread_mutex_t *pMutex = NULL;
212 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
216 ALOGE("%s: Video context info must be supplied", __func__);
217 ret = VIDEO_ERROR_BADPARAM;
221 if (pCtx->pOutMutex != NULL) {
222 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
223 pthread_mutex_destroy(pMutex);
225 pCtx->pOutMutex = NULL;
228 if (pCtx->pInMutex != NULL) {
229 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
230 pthread_mutex_destroy(pMutex);
232 pCtx->pInMutex = NULL;
235 if (pCtx->bShareInbuf == VIDEO_FALSE) {
236 for (i = 0; i < pCtx->nInbufs; i++) {
237 for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) {
238 pVideoPlane = &pCtx->pInbuf[i].planes[j];
239 if (pVideoPlane->addr != NULL) {
240 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
241 pVideoPlane->addr = NULL;
242 pVideoPlane->allocSize = 0;
243 pVideoPlane->dataSize = 0;
246 pCtx->pInbuf[i].pGeometry = NULL;
247 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
248 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
253 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
254 for (i = 0; i < pCtx->nOutbufs; i++) {
255 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
256 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
257 if (pVideoPlane->addr != NULL) {
258 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
259 pVideoPlane->addr = NULL;
260 pVideoPlane->allocSize = 0;
261 pVideoPlane->dataSize = 0;
264 pCtx->pOutbuf[i].pGeometry = NULL;
265 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
266 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
271 if (pCtx->pInbuf != NULL)
274 if (pCtx->pOutbuf != NULL)
287 * [Decoder OPS] Set Frame Tag
289 static ExynosVideoErrorType MFC_Decoder_Set_FrameTag(
293 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
294 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
297 ALOGE("%s: Video context info must be supplied", __func__);
298 ret = VIDEO_ERROR_BADPARAM;
302 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG",
303 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) {
304 ret = VIDEO_ERROR_APIFAIL;
314 * [Decoder OPS] Get Frame Tag
316 static int MFC_Decoder_Get_FrameTag(void *pHandle)
318 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
322 ALOGE("%s: Video context info must be supplied", __func__);
326 __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG",
327 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag);
335 * [Decoder OPS] Get Buffer Count
337 static int MFC_Decoder_Get_ActualBufferCount(void *pHandle)
339 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
340 int bufferCount = -1;
343 ALOGE("%s: Video context info must be supplied", __func__);
347 __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MIN_BUFFERS_FOR_CAPTURE",
348 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, &bufferCount);
356 * [Decoder OPS] Set Display Delay
358 static ExynosVideoErrorType MFC_Decoder_Set_DisplayDelay(
362 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
363 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
366 ALOGE("%s: Video context info must be supplied", __func__);
367 ret = VIDEO_ERROR_BADPARAM;
371 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY",
372 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY, delay) != 0) {
373 ret = VIDEO_ERROR_APIFAIL;
382 * [Decoder OPS] Set Immediate Display
384 static ExynosVideoErrorType MFC_Decoder_Set_ImmediateDisplay( void *pHandle)
386 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
387 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
390 ALOGE("%s: Video context info must be supplied", __func__);
391 ret = VIDEO_ERROR_BADPARAM;
395 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY",
396 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY, 1) != 0) {
397 ret = VIDEO_ERROR_APIFAIL;
406 * [Decoder OPS] Enable Packed PB
408 static ExynosVideoErrorType MFC_Decoder_Enable_PackedPB(void *pHandle)
410 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
411 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
414 ALOGE("%s: Video context info must be supplied", __func__);
415 ret = VIDEO_ERROR_BADPARAM;
419 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB",
420 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB, 1) != 0) {
421 ret = VIDEO_ERROR_APIFAIL;
431 * [Decoder OPS] Enable Loop Filter
433 static ExynosVideoErrorType MFC_Decoder_Enable_LoopFilter(void *pHandle)
435 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
436 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
439 ALOGE("%s: Video context info must be supplied", __func__);
440 ret = VIDEO_ERROR_BADPARAM;
444 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER" ,
445 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 1) != 0) {
446 ret = VIDEO_ERROR_APIFAIL;
456 * [Decoder OPS] Enable Slice Mode
458 static ExynosVideoErrorType MFC_Decoder_Enable_SliceMode(void *pHandle)
460 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
461 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
464 ALOGE("%s: Video context info must be supplied", __func__);
465 ret = VIDEO_ERROR_BADPARAM;
469 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE" ,
470 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE, 1) != 0) {
471 ret = VIDEO_ERROR_APIFAIL;
481 * [Decoder OPS] Enable SEI Parsing
483 static ExynosVideoErrorType MFC_Decoder_Enable_SEIParsing(void *pHandle)
485 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
486 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
489 ALOGE("%s: Video context info must be supplied", __func__);
490 ret = VIDEO_ERROR_BADPARAM;
494 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING" ,
495 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING, 1) != 0) {
496 ret = VIDEO_ERROR_APIFAIL;
506 * [Decoder OPS] Get Frame Packing information
508 static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo(
510 ExynosVideoFramePacking *pFramePacking)
512 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
513 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
515 struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM];
516 struct v4l2_ext_controls ext_ctrls;
518 int seiAvailable, seiInfo, seiGridPos, i;
519 unsigned int seiArgmtId;
522 if ((pCtx == NULL) || (pFramePacking == NULL)) {
523 ALOGE("%s: Video context info or FramePacking pointer must be supplied", __func__);
524 ret = VIDEO_ERROR_BADPARAM;
528 memset(pFramePacking, 0, sizeof(*pFramePacking));
529 memset(ext_ctrl, 0, (sizeof(struct v4l2_ext_control) * FRAME_PACK_SEI_INFO_NUM));
531 ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
532 ext_ctrls.count = FRAME_PACK_SEI_INFO_NUM;
533 ext_ctrls.controls = ext_ctrl;
534 ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL;
535 ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID;
536 ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO;
537 ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS;
539 __ta__("exynos_v4l2_g_ext_ctrl : V4L2_CID_MPEG_VIDEO_H264_SEI_FP_XX(AVAIL,ARRGMENT_ID,INFO,GRID_POS)" ,
540 if (exynos_v4l2_g_ext_ctrl(pCtx->hDec, &ext_ctrls) != 0) {
541 ret = VIDEO_ERROR_APIFAIL;
546 seiAvailable = ext_ctrl[0].value;
547 seiArgmtId = ext_ctrl[1].value;
548 seiInfo = ext_ctrl[2].value;
549 seiGridPos = ext_ctrl[3].value;
551 pFramePacking->available = seiAvailable;
552 pFramePacking->arrangement_id = seiArgmtId;
554 pFramePacking->arrangement_cancel_flag = OPERATE_BIT(seiInfo, 0x1, 0);
555 pFramePacking->arrangement_type = OPERATE_BIT(seiInfo, 0x3f, 1);
556 pFramePacking->quincunx_sampling_flag = OPERATE_BIT(seiInfo, 0x1, 8);
557 pFramePacking->content_interpretation_type = OPERATE_BIT(seiInfo, 0x3f, 9);
558 pFramePacking->spatial_flipping_flag = OPERATE_BIT(seiInfo, 0x1, 15);
559 pFramePacking->frame0_flipped_flag = OPERATE_BIT(seiInfo, 0x1, 16);
560 pFramePacking->field_views_flag = OPERATE_BIT(seiInfo, 0x1, 17);
561 pFramePacking->current_frame_is_frame0_flag = OPERATE_BIT(seiInfo, 0x1, 18);
563 pFramePacking->frame0_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 0);
564 pFramePacking->frame0_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 4);
565 pFramePacking->frame1_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 8);
566 pFramePacking->frame1_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 12);
574 * [Decoder OPS] Enable Decode waiting for share Mode,
575 * to make sure destination support is completed and
576 * reset when Destination streamoff
578 static ExynosVideoErrorType MFC_Decoder_Enable_DecodeWait(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;
589 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START" ,
590 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START, 1) != 0) {
591 ret = VIDEO_ERROR_APIFAIL;
603 * [Decoder Buffer OPS] Enable Cacheable (Input)
605 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Inbuf(void *pHandle)
607 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
608 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
611 ALOGE("%s: Video context info must be supplied", __func__);
612 ret = VIDEO_ERROR_BADPARAM;
616 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE" ,
617 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 2) != 0) {
618 ret = VIDEO_ERROR_APIFAIL;
628 * [Decoder Buffer OPS] Enable Cacheable (Output)
630 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Outbuf(void *pHandle)
632 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
633 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
636 ALOGE("%s: Video context info must be supplied", __func__);
637 ret = VIDEO_ERROR_BADPARAM;
641 __ta__("exynos_v4l2_s_ctrl : V4L2_CID_CACHEABLE" ,
642 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 1) != 0) {
643 ret = VIDEO_ERROR_APIFAIL;
653 * [Decoder Buffer OPS] Set Shareable Buffer (Input)
655 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Inbuf(void *pHandle)
657 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
658 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
661 ALOGE("%s: Video context info must be supplied", __func__);
662 ret = VIDEO_ERROR_BADPARAM;
666 pCtx->bShareInbuf = VIDEO_TRUE;
673 * [Decoder Buffer OPS] Set Shareable Buffer (Output)
675 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Outbuf(void *pHandle)
677 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
678 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
681 ALOGE("%s: Video context info must be supplied", __func__);
682 ret = VIDEO_ERROR_BADPARAM;
686 pCtx->bShareOutbuf = VIDEO_TRUE;
693 * [Decoder Buffer OPS] Get Buffer (Input)
695 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Inbuf(
698 ExynosVideoBuffer **pBuffer)
700 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
701 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
704 ALOGE("%s: Video context info must be supplied", __func__);
706 ret = VIDEO_ERROR_BADPARAM;
710 if (pCtx->nInbufs <= nIndex) {
712 ret = VIDEO_ERROR_BADPARAM;
716 *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex];
723 * [Decoder Buffer OPS] Get Buffer (Output)
725 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Outbuf(
728 ExynosVideoBuffer **pBuffer)
730 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
731 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
734 ALOGE("%s: Video context info must be supplied", __func__);
736 ret = VIDEO_ERROR_BADPARAM;
740 if (pCtx->nOutbufs <= nIndex) {
742 ret = VIDEO_ERROR_BADPARAM;
746 *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex];
753 * [Decoder Buffer OPS] Set Geometry (Input)
755 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Inbuf(
757 ExynosVideoGeometry *bufferConf)
759 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
760 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
762 struct v4l2_format fmt;
765 ALOGE("%s: Video context info must be supplied", __func__);
766 ret = VIDEO_ERROR_BADPARAM;
770 if (bufferConf == NULL) {
771 ALOGE("%s: Buffer geometry must be supplied", __func__);
772 ret = VIDEO_ERROR_BADPARAM;
776 memset(&fmt, 0, sizeof(fmt));
778 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
779 fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat);
780 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage;
782 __ta__("exynos_v4l2_s_fmt" ,
783 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) {
784 ret = VIDEO_ERROR_APIFAIL;
789 memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry));
796 * [Decoder Buffer OPS] Set Geometry (Output)
798 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Outbuf(
800 ExynosVideoGeometry *bufferConf)
802 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
803 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
805 struct v4l2_format fmt;
808 ALOGE("%s: Video context info must be supplied", __func__);
809 ret = VIDEO_ERROR_BADPARAM;
813 if (bufferConf == NULL) {
814 ALOGE("%s: Buffer geometry must be supplied", __func__);
815 ret = VIDEO_ERROR_BADPARAM;
819 memset(&fmt, 0, sizeof(fmt));
821 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
822 fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat);
824 __ta__("exynos_v4l2_s_fmt" ,
825 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) {
826 ret = VIDEO_ERROR_APIFAIL;
831 memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry));
838 * [Decoder Buffer OPS] Get Geometry (Output)
840 static ExynosVideoErrorType MFC_Decoder_Get_Geometry_Outbuf(
842 ExynosVideoGeometry *bufferConf)
844 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
845 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
847 struct v4l2_format fmt;
848 struct v4l2_crop crop;
851 ALOGE("%s: Video context info must be supplied", __func__);
852 ret = VIDEO_ERROR_BADPARAM;
856 if (bufferConf == NULL) {
857 ALOGE("%s: Buffer geometry must be supplied", __func__);
858 ret = VIDEO_ERROR_BADPARAM;
862 memset(&fmt, 0, sizeof(fmt));
863 memset(&crop, 0, sizeof(crop));
865 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
867 __ta__("exynos_v4l2_g_fmt" ,
868 if (exynos_v4l2_g_fmt(pCtx->hDec, &fmt) != 0) {
869 ALOGE("%s: exynos_v4l2_g_fmt. ret = %d", __func__, ret);
870 ret = VIDEO_ERROR_APIFAIL;
875 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
877 __ta__("exynos_v4l2_g_crop" ,
878 if (exynos_v4l2_g_crop(pCtx->hDec, &crop) != 0) {
879 ALOGE("%s: exynos_v4l2_g_crop. ret=%d", __func__, ret);
880 ret = VIDEO_ERROR_APIFAIL;
885 bufferConf->nFrameWidth = fmt.fmt.pix_mp.width;
886 bufferConf->nFrameHeight = fmt.fmt.pix_mp.height;
888 bufferConf->cropRect.nTop = crop.c.top;
889 bufferConf->cropRect.nLeft = crop.c.left;
890 bufferConf->cropRect.nWidth = crop.c.width;
891 bufferConf->cropRect.nHeight = crop.c.height;
898 * [Decoder Buffer OPS] Setup (Input)
900 static ExynosVideoErrorType MFC_Decoder_Setup_Inbuf(
902 unsigned int nBufferCount)
904 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
905 ExynosVideoPlane *pVideoPlane = NULL;
906 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
908 struct v4l2_requestbuffers req;
909 struct v4l2_buffer buf;
910 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES];
914 ALOGE("%s: Video context info must be supplied", __func__);
915 ret = VIDEO_ERROR_BADPARAM;
919 if (nBufferCount == 0) {
920 ALOGE("%s: Buffer count must be greater than 0", __func__);
921 ret = VIDEO_ERROR_BADPARAM;
925 ALOGV("%s: setting up inbufs (%d) shared=%s\n", __func__, nBufferCount,
926 pCtx->bShareInbuf ? "true" : "false");
928 memset(&req, 0, sizeof(req));
930 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
931 req.count = nBufferCount;
933 if (pCtx->bShareInbuf == VIDEO_TRUE)
934 req.memory = pCtx->nMemoryType;
936 req.memory = V4L2_MEMORY_MMAP;
938 __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",
939 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
940 ret = VIDEO_ERROR_APIFAIL;
945 if (req.count != nBufferCount) {
946 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count);
947 ret = VIDEO_ERROR_NOMEM;
951 pCtx->nInbufs = (int)req.count;
953 pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
954 if (pCtx->pInbuf == NULL) {
955 ALOGE("Failed to allocate input buffer context");
956 ret = VIDEO_ERROR_NOMEM;
959 memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
961 memset(&buf, 0, sizeof(buf));
963 if (pCtx->bShareInbuf == VIDEO_FALSE) {
964 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
965 buf.memory = V4L2_MEMORY_MMAP;
966 buf.m.planes = planes;
967 buf.length = VIDEO_DECODER_INBUF_PLANES;
969 ALOGV("[%s] INBUF V4L2_MEMORY_MMAP", __func__);
970 for (i = 0; i < pCtx->nInbufs; i++) {
972 __ta__("INBUF : exynos_v4l2_querybuf",
973 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) {
974 ret = VIDEO_ERROR_APIFAIL;
979 pVideoPlane = &pCtx->pInbuf[i].planes[0];
981 __ta__("mmap : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",
982 pVideoPlane->addr = mmap(NULL,
983 buf.m.planes[0].length, PROT_READ | PROT_WRITE,
984 MAP_SHARED, pCtx->hDec, buf.m.planes[0].m.mem_offset);
987 if (pVideoPlane->addr == MAP_FAILED) {
988 ret = VIDEO_ERROR_MAPFAIL;
992 pVideoPlane->allocSize = buf.m.planes[0].length;
993 pVideoPlane->dataSize = 0;
995 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
996 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
997 pCtx->pInbuf[i].bRegistered = VIDEO_TRUE;
1004 if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) {
1005 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1006 for (i = 0; i < pCtx->nInbufs; i++) {
1007 pVideoPlane = &pCtx->pInbuf[i].planes[0];
1008 if (pVideoPlane->addr == MAP_FAILED) {
1009 pVideoPlane->addr = NULL;
1013 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1024 * [Decoder Buffer OPS] Setup (Output)
1026 static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf(
1028 unsigned int nBufferCount)
1030 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1031 ExynosVideoPlane *pVideoPlane = NULL;
1032 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1034 struct v4l2_requestbuffers req;
1035 struct v4l2_buffer buf;
1036 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES];
1040 ALOGE("%s: Video context info must be supplied", __func__);
1041 ret = VIDEO_ERROR_BADPARAM;
1045 if (nBufferCount == 0) {
1046 ALOGE("%s: Buffer count must be greater than 0", __func__);
1047 ret = VIDEO_ERROR_BADPARAM;
1051 ALOGV("%s: setting up outbufs (%d) shared=%s\n", __func__, nBufferCount,
1052 pCtx->bShareOutbuf ? "true" : "false");
1054 memset(&req, 0, sizeof(req));
1056 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1057 req.count = nBufferCount;
1059 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1060 req.memory = pCtx->nMemoryType;
1062 req.memory = V4L2_MEMORY_MMAP;
1064 __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" ,
1065 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1066 ret = VIDEO_ERROR_APIFAIL;
1071 if (req.count != nBufferCount) {
1072 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count);
1073 ret = VIDEO_ERROR_NOMEM;
1077 pCtx->nOutbufs = req.count;
1079 pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1080 if (pCtx->pOutbuf == NULL) {
1081 ALOGE("Failed to allocate output buffer context");
1082 ret = VIDEO_ERROR_NOMEM;
1085 memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1087 memset(&buf, 0, sizeof(buf));
1089 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1090 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1091 buf.memory = V4L2_MEMORY_MMAP;
1092 buf.m.planes = planes;
1093 buf.length = VIDEO_DECODER_OUTBUF_PLANES;
1095 ALOGV("[%s] OUTBUF V4L2_MEMORY_MMAP", __func__);
1096 for (i = 0; i < pCtx->nOutbufs; i++) {
1098 __ta__("exynos_v4l2_querybuf" ,
1099 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) {
1100 ret = VIDEO_ERROR_APIFAIL;
1105 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1106 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1107 __ta__("mmap : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",
1108 pVideoPlane->addr = mmap(NULL,
1109 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1110 MAP_SHARED, pCtx->hDec, buf.m.planes[j].m.mem_offset);
1113 if (pVideoPlane->addr == MAP_FAILED) {
1114 ret = VIDEO_ERROR_MAPFAIL;
1118 pVideoPlane->allocSize = buf.m.planes[j].length;
1119 pVideoPlane->dataSize = 0;
1121 #ifdef SLP_PLATFORM /* dmabuf */
1122 __ta__("exynos_v4l2_expbuf" ,
1123 // if (pCtx->bufShareMethod == BUF_SHARE_FD) {
1124 exynos_v4l2_expbuf(pCtx->hDec, &pVideoPlane->fd, buf.m.planes[j].m.mem_offset);
1125 ALOGV("[%s] fd (%d) received from MFC", __func__, pVideoPlane->fd);
1131 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1132 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1133 pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE;
1140 if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) {
1141 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1142 for (i = 0; i < pCtx->nOutbufs; i++) {
1143 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1144 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1145 if (pVideoPlane->addr == MAP_FAILED) {
1146 pVideoPlane->addr = NULL;
1150 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1155 free(pCtx->pOutbuf);
1162 * [Decoder Buffer OPS] Run (Input)
1164 static ExynosVideoErrorType MFC_Decoder_Run_Inbuf(void *pHandle)
1166 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1167 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1170 ALOGE("%s: Video context info must be supplied", __func__);
1171 ret = VIDEO_ERROR_BADPARAM;
1175 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1176 __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" ,
1177 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1178 ALOGE("%s: Failed to streamon for input buffer", __func__);
1179 ret = VIDEO_ERROR_APIFAIL;
1183 pCtx->bStreamonInbuf = VIDEO_TRUE;
1191 * [Decoder Buffer OPS] Run (Output)
1193 static ExynosVideoErrorType MFC_Decoder_Run_Outbuf(void *pHandle)
1195 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1196 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_FALSE) {
1205 __ta__("exynos_v4l2_streamon : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" ,
1206 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1207 ALOGE("%s: Failed to streamon for output buffer", __func__);
1208 ret = VIDEO_ERROR_APIFAIL;
1212 pCtx->bStreamonOutbuf = VIDEO_TRUE;
1220 * [Decoder Buffer OPS] Stop (Input)
1222 static ExynosVideoErrorType MFC_Decoder_Stop_Inbuf(void *pHandle)
1224 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1225 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1229 ALOGE("%s: Video context info must be supplied", __func__);
1230 ret = VIDEO_ERROR_BADPARAM;
1234 if (pCtx->bStreamonInbuf == VIDEO_TRUE) {
1235 __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" ,
1236 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1237 ALOGE("%s: Failed to streamoff for input buffer", __func__);
1238 ret = VIDEO_ERROR_APIFAIL;
1242 pCtx->bStreamonInbuf = VIDEO_FALSE;
1245 for (i = 0; i < pCtx->nInbufs; i++) {
1246 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1254 * [Decoder Buffer OPS] Stop (Output)
1256 static ExynosVideoErrorType MFC_Decoder_Stop_Outbuf(void *pHandle)
1258 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1259 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1263 ALOGE("%s: Video context info must be supplied", __func__);
1264 ret = VIDEO_ERROR_BADPARAM;
1268 if (pCtx->bStreamonOutbuf == VIDEO_TRUE) {
1269 __ta__("exynos_v4l2_streamoff : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" ,
1270 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1271 ALOGE("%s: Failed to streamoff for output buffer", __func__);
1272 ret = VIDEO_ERROR_APIFAIL;
1276 pCtx->bStreamonOutbuf = VIDEO_FALSE;
1279 for (i = 0; i < pCtx->nOutbufs; i++) {
1280 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1288 * [Decoder Buffer OPS] Wait (Input)
1290 static ExynosVideoErrorType MFC_Decoder_Wait_Inbuf(void *pHandle)
1292 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1293 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1295 struct pollfd poll_events;
1299 ALOGE("%s: Video context info must be supplied", __func__);
1300 ret = VIDEO_ERROR_BADPARAM;
1304 poll_events.fd = pCtx->hDec;
1305 poll_events.events = POLLOUT | POLLERR;
1306 poll_events.revents = 0;
1309 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_DECODER_POLL_TIMEOUT);
1310 if (poll_state > 0) {
1311 if (poll_events.revents & POLLOUT) {
1314 ALOGE("%s: Poll return error", __func__);
1315 ret = VIDEO_ERROR_POLL;
1318 } else if (poll_state < 0) {
1319 ALOGE("%s: Poll state error", __func__);
1320 ret = VIDEO_ERROR_POLL;
1323 } while (poll_state == 0);
1329 static ExynosVideoErrorType MFC_Decoder_Register_Inbuf(
1331 ExynosVideoPlane *planes,
1334 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1335 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1338 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_INBUF_PLANES)) {
1339 ALOGE("%s: params must be supplied", __func__);
1340 ret = VIDEO_ERROR_BADPARAM;
1344 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1345 if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) {
1346 for (plane = 0; plane < nPlanes; plane++) {
1347 pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr;
1348 pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1349 pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd;
1350 ALOGV("%s: registered buf %d (addr=%p alloc_sz=%ld fd=%d)\n", __func__, nIndex,
1351 planes[plane].addr, planes[plane].allocSize, planes[plane].fd);
1353 pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE;
1358 if (nIndex == pCtx->nInbufs) {
1359 ALOGE("%s: can not find non-registered input buffer", __func__);
1360 ret = VIDEO_ERROR_NOBUFFERS;
1367 static ExynosVideoErrorType MFC_Decoder_Register_Outbuf(
1369 ExynosVideoPlane *planes,
1372 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1373 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1376 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_OUTBUF_PLANES)) {
1377 ALOGE("%s: params must be supplied", __func__);
1378 ret = VIDEO_ERROR_BADPARAM;
1382 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1383 if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) {
1384 for (plane = 0; plane < nPlanes; plane++) {
1385 pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr;
1386 pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1387 pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd;
1389 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE;
1390 ALOGV("%s: registered buf %d 0:(addr=%p alloc_sz=%d fd=%d) 1:(addr=%p alloc_sz=%d fd=%d)\n",
1391 __func__, nIndex, planes[0].addr, planes[0].allocSize, planes[0].fd,
1392 planes[1].addr, planes[1].allocSize, planes[1].fd);
1397 if (nIndex == pCtx->nOutbufs) {
1398 ALOGE("%s: can not find non-registered output buffer", __func__);
1399 ret = VIDEO_ERROR_NOBUFFERS;
1406 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
1408 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1409 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1413 ALOGE("%s: Video context info must be supplied", __func__);
1414 ret = VIDEO_ERROR_BADPARAM;
1418 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1419 pCtx->pInbuf[nIndex].planes[0].addr = NULL;
1420 pCtx->pInbuf[nIndex].planes[0].fd = -1;
1421 pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE;
1428 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
1430 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1431 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1435 ALOGE("%s: Video context info must be supplied", __func__);
1436 ret = VIDEO_ERROR_BADPARAM;
1440 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1441 pCtx->pOutbuf[nIndex].planes[0].addr = NULL;
1442 pCtx->pOutbuf[nIndex].planes[0].fd = -1;
1443 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE;
1451 * [Decoder Buffer OPS] Find (Input)
1453 static int MFC_Decoder_Find_Inbuf(
1455 unsigned char *pBuffer)
1457 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1461 ALOGE("%s: Video context info must be supplied", __func__);
1465 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1466 if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) {
1467 if ((pBuffer == NULL) ||
1468 (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer))
1473 if (nIndex == pCtx->nInbufs)
1481 * [Decoder Buffer OPS] Find (Outnput)
1483 static int MFC_Decoder_Find_Outbuf(
1485 unsigned char *pBuffer)
1487 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1491 ALOGE("%s: Video context info must be supplied", __func__);
1495 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1496 if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) {
1497 if ((pBuffer == NULL) ||
1498 (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer))
1503 if (nIndex == pCtx->nOutbufs)
1511 * [Decoder Buffer OPS] Enqueue (Input)
1513 static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf(
1515 unsigned char *pBuffer[],
1516 unsigned int dataSize[],
1520 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1521 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1522 pthread_mutex_t *pMutex = NULL;
1524 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES];
1525 struct v4l2_buffer buf;
1529 ALOGE("%s: Video context info must be supplied", __func__);
1530 ret = VIDEO_ERROR_BADPARAM;
1534 if (VIDEO_DECODER_INBUF_PLANES < nPlanes) {
1535 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1536 VIDEO_DECODER_INBUF_PLANES, nPlanes);
1537 ret = VIDEO_ERROR_BADPARAM;
1541 memset(&buf, 0, sizeof(buf));
1543 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1544 buf.m.planes = planes;
1545 buf.length = VIDEO_DECODER_INBUF_PLANES;
1547 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
1548 pthread_mutex_lock(pMutex);
1549 index = MFC_Decoder_Find_Inbuf(pCtx, pBuffer[0]);
1551 pthread_mutex_unlock(pMutex);
1552 ALOGE("%s: Failed to get index", __func__);
1553 ret = VIDEO_ERROR_NOBUFFERS;
1558 pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE;
1559 pthread_mutex_unlock(pMutex);
1561 if (pCtx->bShareInbuf == VIDEO_TRUE) {
1562 buf.memory = pCtx->nMemoryType;
1563 for (i = 0; i < nPlanes; i++) {
1564 /* V4L2_MEMORY_USERPTR */
1565 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1566 /* V4L2_MEMORY_DMABUF */
1568 buf.m.planes[i].m.fd = pCtx->pInbuf[index].planes[i].fd;
1570 buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize;
1571 buf.m.planes[i].bytesused = dataSize[i];
1572 ALOGV("%s: shared INBUF(%d) plane(%d) data_offset= %x addr=%p len=%d used=%d\n", __func__,
1574 buf.m.planes[i].data_offset,
1575 buf.m.planes[i].m.userptr,
1576 buf.m.planes[i].length,
1577 buf.m.planes[i].bytesused);
1580 buf.memory = V4L2_MEMORY_MMAP;
1581 for (i = 0; i < nPlanes; i++)
1582 buf.m.planes[i].bytesused = dataSize[i];
1585 __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" ,
1586 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) {
1587 ALOGE("%s: Failed to enqueue input buffer", __func__);
1588 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1589 ret = VIDEO_ERROR_APIFAIL;
1594 pCtx->pInbuf[buf.index].pPrivate = pPrivate;
1601 * [Decoder Buffer OPS] Enqueue (Output)
1603 static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf(
1605 unsigned char *pBuffer[],
1606 unsigned int dataSize[],
1610 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1611 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1612 pthread_mutex_t *pMutex = NULL;
1614 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES];
1615 struct v4l2_buffer buf;
1619 ALOGE("%s: Video context info must be supplied", __func__);
1620 ret = VIDEO_ERROR_BADPARAM;
1624 if (VIDEO_DECODER_OUTBUF_PLANES < nPlanes) {
1625 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1626 VIDEO_DECODER_OUTBUF_PLANES, nPlanes);
1627 ret = VIDEO_ERROR_BADPARAM;
1631 memset(&buf, 0, sizeof(buf));
1633 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1634 buf.m.planes = planes;
1635 buf.length = VIDEO_DECODER_OUTBUF_PLANES;
1637 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
1638 pthread_mutex_lock(pMutex);
1639 index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]);
1641 pthread_mutex_unlock(pMutex);
1642 ALOGE("%s: Failed to get index", __func__);
1643 ret = VIDEO_ERROR_NOBUFFERS;
1647 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE;
1648 pthread_mutex_unlock(pMutex);
1650 if (pCtx->bShareOutbuf == VIDEO_TRUE) {
1651 buf.memory = pCtx->nMemoryType;
1652 for (i = 0; i < nPlanes; i++) {
1653 /* V4L2_MEMORY_USERPTR */
1654 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1655 /* V4L2_MEMORY_DMABUF */
1657 buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd;
1659 buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize;
1660 buf.m.planes[i].bytesused = dataSize[i];
1661 ALOGV("%s: shared OUTBUF(%d) plane=%d data_offset= %x addr=0x%lx len=%d used=%d\n", __func__,
1663 buf.m.planes[i].data_offset,
1664 buf.m.planes[i].m.userptr,
1665 buf.m.planes[i].length,
1666 buf.m.planes[i].bytesused);
1669 ALOGV("%s: non-shared outbuf(%d)\n", __func__, index);
1670 buf.memory = V4L2_MEMORY_MMAP;
1673 __ta__("exynos_v4l2_qbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" ,
1674 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) {
1675 ALOGE("%s: Failed to enqueue output buffer", __func__);
1676 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE;
1677 ret = VIDEO_ERROR_APIFAIL;
1682 pCtx->pOutbuf[buf.index].pPrivate = pPrivate;
1689 * [Decoder Buffer OPS] Dequeue (Input)
1691 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle)
1693 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1694 ExynosVideoBuffer *pInbuf = NULL;
1696 struct v4l2_buffer buf;
1699 ALOGE("%s: Video context info must be supplied", __func__);
1703 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1708 memset(&buf, 0, sizeof(buf));
1710 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1712 if (pCtx->bShareInbuf == VIDEO_TRUE)
1713 buf.memory = pCtx->nMemoryType;
1715 buf.memory = V4L2_MEMORY_MMAP;
1717 __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" ,
1718 if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) {
1724 pInbuf = &pCtx->pInbuf[buf.index];
1725 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1727 if (pCtx->bStreamonInbuf == VIDEO_FALSE)
1735 * [Decoder Buffer OPS] Dequeue (Output)
1737 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle)
1739 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1740 ExynosVideoBuffer *pOutbuf = NULL;
1742 struct v4l2_buffer buf;
1748 ALOGE("%s: Video context info must be supplied", __func__);
1752 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1757 memset(&buf, 0, sizeof(buf));
1758 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1760 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1761 buf.memory = pCtx->nMemoryType;
1763 buf.memory = V4L2_MEMORY_MMAP;
1765 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
1766 __ta__("exynos_v4l2_dqbuf : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",
1767 ret = exynos_v4l2_dqbuf(pCtx->hDec, &buf);
1771 pOutbuf = (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO;
1777 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1782 pOutbuf = &pCtx->pOutbuf[buf.index];
1784 __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS",
1785 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value);
1788 ALOGV("%s: V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS value = %d", __func__, value);
1791 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY;
1794 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING;
1797 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY;
1800 __ta__("exynos_v4l2_g_ctrl : V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE",
1801 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state);
1803 if (state == 1) /* Resolution change is detected */
1804 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
1805 else /* Decoding is finished */
1806 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED;
1809 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1813 switch (buf.flags & (0x7 << 3)) {
1814 ALOGV("%s: frameType: %d", __func__, buf.flags & (0x7 << 3));
1815 case V4L2_BUF_FLAG_KEYFRAME:
1816 pOutbuf->frameType = VIDEO_FRAME_I;
1818 case V4L2_BUF_FLAG_PFRAME:
1819 pOutbuf->frameType = VIDEO_FRAME_P;
1821 case V4L2_BUF_FLAG_BFRAME:
1822 pOutbuf->frameType = VIDEO_FRAME_B;
1825 pOutbuf->frameType = VIDEO_FRAME_OTHERS;
1829 pOutbuf->bQueued = VIDEO_FALSE;
1835 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Inbuf(void *pHandle)
1837 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1838 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1842 ALOGE("%s: Video context info must be supplied", __func__);
1843 ret = VIDEO_ERROR_BADPARAM;
1847 for (i = 0; i < pCtx->nInbufs; i++) {
1848 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1855 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Outbuf(void *pHandle)
1857 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1858 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1862 ALOGE("%s: Video context info must be supplied", __func__);
1863 ret = VIDEO_ERROR_BADPARAM;
1867 for (i = 0; i < pCtx->nOutbufs; i++) {
1868 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1875 /* [Decoder Buffer OPS] Cleanup (Input)
1877 static ExynosVideoErrorType MFC_Decoder_Cleanup_Inbuf(void *pHandle)
1879 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1880 ExynosVideoPlane *pVideoPlane = NULL;
1881 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1883 struct v4l2_requestbuffers req;
1884 int nBufferCount, i, j;
1887 ALOGE("%s: Video context info must be supplied", __func__);
1888 ret = VIDEO_ERROR_BADPARAM;
1892 nBufferCount = 0; /* for Clean-up */
1894 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1895 for (i = 0; i < pCtx->nInbufs; i++) {
1896 for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) {
1897 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1898 if (pVideoPlane->addr != NULL) {
1899 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1900 pVideoPlane->addr = NULL;
1901 pVideoPlane->allocSize = 0;
1902 pVideoPlane->dataSize = 0;
1905 pCtx->pInbuf[i].pGeometry = NULL;
1906 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1907 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
1912 memset(&req, 0, sizeof(req));
1914 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1915 req.count = nBufferCount;
1917 if (pCtx->bShareInbuf == VIDEO_TRUE)
1918 req.memory = pCtx->nMemoryType;
1920 req.memory = V4L2_MEMORY_MMAP;
1922 __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" ,
1923 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1924 ret = VIDEO_ERROR_APIFAIL;
1929 pCtx->nInbufs = (int)req.count;
1931 if (pCtx->pInbuf != NULL)
1939 * [Decoder Buffer OPS] Cleanup (Output)
1941 static ExynosVideoErrorType MFC_Decoder_Cleanup_Outbuf(void *pHandle)
1943 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1944 ExynosVideoPlane *pVideoPlane = NULL;
1945 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1947 struct v4l2_requestbuffers req;
1948 int nBufferCount, i ,j;
1951 ALOGE("%s: Video context info must be supplied", __func__);
1952 ret = VIDEO_ERROR_BADPARAM;
1956 nBufferCount = 0; /* for Clean-up */
1958 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1959 for (i = 0; i < pCtx->nOutbufs; i++) {
1960 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1961 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1962 if (pVideoPlane->addr != NULL) {
1963 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1964 pVideoPlane->addr = NULL;
1965 pVideoPlane->allocSize = 0;
1966 pVideoPlane->dataSize = 0;
1969 pCtx->pOutbuf[i].pGeometry = NULL;
1970 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1971 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
1976 memset(&req, 0, sizeof(req));
1978 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1979 req.count = nBufferCount;
1981 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1982 req.memory = pCtx->nMemoryType;
1984 req.memory = V4L2_MEMORY_MMAP;
1986 __ta__("exynos_v4l2_reqbufs : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" ,
1987 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1988 ALOGE("reqbuf fail");
1989 ret = VIDEO_ERROR_APIFAIL;
1994 pCtx->nOutbufs = req.count;
1996 if (pCtx->pOutbuf != NULL)
1997 free(pCtx->pOutbuf);
2004 * [Decoder OPS] Common
2006 static ExynosVideoDecOps defDecOps = {
2008 .Init = MFC_Decoder_Init,
2009 .Finalize = MFC_Decoder_Finalize,
2010 .Set_DisplayDelay = MFC_Decoder_Set_DisplayDelay,
2011 .Enable_PackedPB = MFC_Decoder_Enable_PackedPB,
2012 .Enable_LoopFilter = MFC_Decoder_Enable_LoopFilter,
2013 .Enable_SliceMode = MFC_Decoder_Enable_SliceMode,
2014 .Get_ActualBufferCount = MFC_Decoder_Get_ActualBufferCount,
2015 .Set_FrameTag = MFC_Decoder_Set_FrameTag,
2016 .Get_FrameTag = MFC_Decoder_Get_FrameTag,
2017 .Enable_SEIParsing = MFC_Decoder_Enable_SEIParsing,
2018 .Get_FramePackingInfo = MFC_Decoder_Get_FramePackingInfo,
2019 .Set_ImmediateDisplay = MFC_Decoder_Set_ImmediateDisplay,
2020 .Enable_DecodeWait = MFC_Decoder_Enable_DecodeWait,
2024 * [Decoder Buffer OPS] Input
2026 static ExynosVideoDecBufferOps defInbufOps = {
2028 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Inbuf,
2029 .Set_Shareable = MFC_Decoder_Set_Shareable_Inbuf,
2030 .Get_Buffer = MFC_Decoder_Get_Buffer_Inbuf,
2031 .Set_Geometry = MFC_Decoder_Set_Geometry_Inbuf,
2032 .Get_Geometry = NULL,
2033 .Setup = MFC_Decoder_Setup_Inbuf,
2034 .Run = MFC_Decoder_Run_Inbuf,
2035 .Stop = MFC_Decoder_Stop_Inbuf,
2036 .Enqueue = MFC_Decoder_Enqueue_Inbuf,
2037 .Enqueue_All = NULL,
2038 .Dequeue = MFC_Decoder_Dequeue_Inbuf,
2039 .Register = MFC_Decoder_Register_Inbuf,
2040 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Inbuf,
2041 .Clear_Queue = MFC_Decoder_Clear_Queued_Inbuf,
2042 .Cleanup = MFC_Decoder_Cleanup_Inbuf,
2046 * [Decoder Buffer OPS] Output
2048 static ExynosVideoDecBufferOps defOutbufOps = {
2050 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Outbuf,
2051 .Set_Shareable = MFC_Decoder_Set_Shareable_Outbuf,
2052 .Get_Buffer = MFC_Decoder_Get_Buffer_Outbuf,
2053 .Set_Geometry = MFC_Decoder_Set_Geometry_Outbuf,
2054 .Get_Geometry = MFC_Decoder_Get_Geometry_Outbuf,
2055 .Setup = MFC_Decoder_Setup_Outbuf,
2056 .Run = MFC_Decoder_Run_Outbuf,
2057 .Stop = MFC_Decoder_Stop_Outbuf,
2058 .Enqueue = MFC_Decoder_Enqueue_Outbuf,
2059 .Enqueue_All = NULL,
2060 .Dequeue = MFC_Decoder_Dequeue_Outbuf,
2061 .Register = MFC_Decoder_Register_Outbuf,
2062 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Outbuf,
2063 .Clear_Queue = MFC_Decoder_Clear_Queued_Outbuf,
2064 .Cleanup = MFC_Decoder_Cleanup_Outbuf,
2067 int Exynos_Video_Register_Decoder(
2068 ExynosVideoDecOps *pDecOps,
2069 ExynosVideoDecBufferOps *pInbufOps,
2070 ExynosVideoDecBufferOps *pOutbufOps)
2072 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2074 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
2075 ret = VIDEO_ERROR_BADPARAM;
2079 defDecOps.nSize = sizeof(defDecOps);
2080 defInbufOps.nSize = sizeof(defInbufOps);
2081 defOutbufOps.nSize = sizeof(defOutbufOps);
2083 memcpy((char *)pDecOps + sizeof(pDecOps->nSize), (char *)&defDecOps + sizeof(defDecOps.nSize),
2084 pDecOps->nSize - sizeof(pDecOps->nSize));
2086 memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
2087 pInbufOps->nSize - sizeof(pInbufOps->nSize));
2089 memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
2090 pOutbufOps->nSize - sizeof(pOutbufOps->nSize));