3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 * @file ExynosVideoDecoder.c
21 * @author Jinsung Yang (jsgood.yang@samsung.com)
24 * 2012.01.15: Initial Version
34 #include <sys/types.h>
36 #include <sys/ioctl.h>
42 #include "ExynosVideoApi.h"
43 #include "ExynosVideoDec.h"
45 /* #define LOG_NDEBUG 0 */
46 #define LOG_TAG "ExynosVideoDecoder"
47 #ifndef TIZEN_FEATURE_E3250 /* build env */
48 #include <utils/Log.h>
50 #include "Exynos_OSAL_Log.h"
54 * [Common] __CodingType_To_V4L2PixelFormat
56 static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType)
58 unsigned int pixelformat = V4L2_PIX_FMT_H264;
61 case VIDEO_CODING_AVC:
62 pixelformat = V4L2_PIX_FMT_H264;
64 case VIDEO_CODING_MPEG4:
65 pixelformat = V4L2_PIX_FMT_MPEG4;
67 case VIDEO_CODING_VP8:
68 pixelformat = V4L2_PIX_FMT_VP8;
70 case VIDEO_CODING_H263:
71 pixelformat = V4L2_PIX_FMT_H263;
73 case VIDEO_CODING_VC1:
74 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G;
76 case VIDEO_CODING_VC1_RCV:
77 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L;
79 case VIDEO_CODING_MPEG2:
80 pixelformat = V4L2_PIX_FMT_MPEG2;
83 pixelformat = V4L2_PIX_FMT_H264;
91 * [Common] __ColorFormatType_To_V4L2PixelFormat
93 static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType)
95 unsigned int pixelformat = V4L2_PIX_FMT_NV12M;
97 switch (colorFormatType) {
98 case VIDEO_COLORFORMAT_NV12_TILED:
100 pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
102 pixelformat = V4L2_PIX_FMT_NV12MT;
106 case VIDEO_COLORFORMAT_NV21:
107 pixelformat = V4L2_PIX_FMT_NV21M;
109 case VIDEO_COLORFORMAT_NV12:
112 pixelformat = V4L2_PIX_FMT_NV12M;
122 static void *MFC_Decoder_Init(int nMemoryType)
124 ExynosVideoDecContext *pCtx = NULL;
125 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 pCtx->pInMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
155 if (pCtx->pInMutex == NULL) {
156 ALOGE("%s: Failed to allocate mutex about input buffer", __func__);
157 goto EXIT_QUERYCAP_FAIL;
159 if (pthread_mutex_init(pCtx->pInMutex, NULL) != 0) {
160 goto EXIT_QUERYCAP_FAIL;
163 pCtx->pOutMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
164 if (pCtx->pOutMutex == NULL) {
165 ALOGE("%s: Failed to allocate mutex about output buffer", __func__);
166 goto EXIT_QUERYCAP_FAIL;
168 if (pthread_mutex_init(pCtx->pOutMutex, NULL) != 0) {
169 goto EXIT_QUERYCAP_FAIL;
175 if (pCtx->pInMutex != NULL) {
176 pthread_mutex_destroy(pCtx->pInMutex);
177 free(pCtx->pInMutex);
180 if (pCtx->pOutMutex != NULL) {
181 pthread_mutex_destroy(pCtx->pOutMutex);
182 free(pCtx->pOutMutex);
195 * [Decoder OPS] Finalize
197 static ExynosVideoErrorType MFC_Decoder_Finalize(void *pHandle)
199 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
200 ExynosVideoPlane *pVideoPlane = NULL;
201 pthread_mutex_t *pMutex = NULL;
202 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
206 ALOGE("%s: Video context info must be supplied", __func__);
207 ret = VIDEO_ERROR_BADPARAM;
211 if (pCtx->pOutMutex != NULL) {
212 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
213 pthread_mutex_destroy(pMutex);
215 pCtx->pOutMutex = NULL;
218 if (pCtx->pInMutex != NULL) {
219 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
220 pthread_mutex_destroy(pMutex);
222 pCtx->pInMutex = NULL;
225 if (pCtx->bShareInbuf == VIDEO_FALSE) {
226 for (i = 0; i < pCtx->nInbufs; i++) {
227 for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) {
228 pVideoPlane = &pCtx->pInbuf[i].planes[j];
229 if (pVideoPlane->addr != NULL) {
230 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
231 pVideoPlane->addr = NULL;
232 pVideoPlane->allocSize = 0;
233 pVideoPlane->dataSize = 0;
236 pCtx->pInbuf[i].pGeometry = NULL;
237 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
238 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
243 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
244 for (i = 0; i < pCtx->nOutbufs; i++) {
245 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
246 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
247 if (pVideoPlane->addr != NULL) {
248 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
249 pVideoPlane->addr = NULL;
250 pVideoPlane->allocSize = 0;
251 pVideoPlane->dataSize = 0;
254 pCtx->pOutbuf[i].pGeometry = NULL;
255 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
256 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
261 if (pCtx->pInbuf != NULL)
264 if (pCtx->pOutbuf != NULL)
277 * [Decoder OPS] Set Frame Tag
279 static ExynosVideoErrorType MFC_Decoder_Set_FrameTag(
283 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
284 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
285 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
287 ALOGE("%s: Video context info must be supplied", __func__);
288 ret = VIDEO_ERROR_BADPARAM;
292 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) {
293 ret = VIDEO_ERROR_APIFAIL;
303 * [Decoder OPS] Get Frame Tag
305 static int MFC_Decoder_Get_FrameTag(void *pHandle)
307 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
311 ALOGE("%s: Video context info must be supplied", __func__);
314 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
315 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag);
322 * [Decoder OPS] Get Buffer Count
324 static int MFC_Decoder_Get_ActualBufferCount(void *pHandle)
326 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
327 int bufferCount = -1;
330 ALOGE("%s: Video context info must be supplied", __func__);
334 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, &bufferCount);
341 * [Decoder OPS] Set Display Delay
343 static ExynosVideoErrorType MFC_Decoder_Set_DisplayDelay(
347 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
348 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
351 ALOGE("%s: Video context info must be supplied", __func__);
352 ret = VIDEO_ERROR_BADPARAM;
356 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY, delay) != 0) {
357 ret = VIDEO_ERROR_APIFAIL;
365 * [Decoder OPS] Set Immediate Display
367 static ExynosVideoErrorType MFC_Decoder_Set_ImmediateDisplay( void *pHandle)
369 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
370 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
371 #ifdef V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY
373 ALOGE("%s: Video context info must be supplied", __func__);
374 ret = VIDEO_ERROR_BADPARAM;
378 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY, 1) != 0) {
379 ret = VIDEO_ERROR_APIFAIL;
387 * [Decoder OPS] Enable Packed PB
389 static ExynosVideoErrorType MFC_Decoder_Enable_PackedPB(void *pHandle)
391 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
392 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
395 ALOGE("%s: Video context info must be supplied", __func__);
396 ret = VIDEO_ERROR_BADPARAM;
399 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB
400 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB, 1) != 0) {
401 ret = VIDEO_ERROR_APIFAIL;
410 * [Decoder OPS] Enable Loop Filter
412 static ExynosVideoErrorType MFC_Decoder_Enable_LoopFilter(void *pHandle)
414 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
415 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
418 ALOGE("%s: Video context info must be supplied", __func__);
419 ret = VIDEO_ERROR_BADPARAM;
423 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 1) != 0) {
424 ret = VIDEO_ERROR_APIFAIL;
433 * [Decoder OPS] Enable Slice Mode
435 static ExynosVideoErrorType MFC_Decoder_Enable_SliceMode(void *pHandle)
437 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
438 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
441 ALOGE("%s: Video context info must be supplied", __func__);
442 ret = VIDEO_ERROR_BADPARAM;
446 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE, 1) != 0) {
447 ret = VIDEO_ERROR_APIFAIL;
456 * [Decoder OPS] Enable SEI Parsing
458 static ExynosVideoErrorType MFC_Decoder_Enable_SEIParsing(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 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING, 1) != 0) {
470 ret = VIDEO_ERROR_APIFAIL;
479 * [Decoder OPS] Get Frame Packing information
481 static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo(
483 ExynosVideoFramePacking *pFramePacking)
485 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
486 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
487 #ifdef V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL
488 struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM];
489 struct v4l2_ext_controls ext_ctrls;
491 int seiAvailable, seiInfo, seiGridPos;
492 unsigned int seiArgmtId;
495 if ((pCtx == NULL) || (pFramePacking == NULL)) {
496 ALOGE("%s: Video context info or FramePacking pointer must be supplied", __func__);
497 ret = VIDEO_ERROR_BADPARAM;
501 memset(pFramePacking, 0, sizeof(*pFramePacking));
502 memset(ext_ctrl, 0, (sizeof(struct v4l2_ext_control) * FRAME_PACK_SEI_INFO_NUM));
504 ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
505 ext_ctrls.count = FRAME_PACK_SEI_INFO_NUM;
506 ext_ctrls.controls = ext_ctrl;
507 ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL;
508 ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID;
509 ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO;
510 ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS;
512 if (exynos_v4l2_g_ext_ctrl(pCtx->hDec, &ext_ctrls) != 0) {
513 ret = VIDEO_ERROR_APIFAIL;
517 seiAvailable = ext_ctrl[0].value;
518 seiArgmtId = ext_ctrl[1].value;
519 seiInfo = ext_ctrl[2].value;
520 seiGridPos = ext_ctrl[3].value;
522 pFramePacking->available = seiAvailable;
523 pFramePacking->arrangement_id = seiArgmtId;
525 pFramePacking->arrangement_cancel_flag = OPERATE_BIT(seiInfo, 0x1, 0);
526 pFramePacking->arrangement_type = OPERATE_BIT(seiInfo, 0x3f, 1);
527 pFramePacking->quincunx_sampling_flag = OPERATE_BIT(seiInfo, 0x1, 8);
528 pFramePacking->content_interpretation_type = OPERATE_BIT(seiInfo, 0x3f, 9);
529 pFramePacking->spatial_flipping_flag = OPERATE_BIT(seiInfo, 0x1, 15);
530 pFramePacking->frame0_flipped_flag = OPERATE_BIT(seiInfo, 0x1, 16);
531 pFramePacking->field_views_flag = OPERATE_BIT(seiInfo, 0x1, 17);
532 pFramePacking->current_frame_is_frame0_flag = OPERATE_BIT(seiInfo, 0x1, 18);
534 pFramePacking->frame0_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 0);
535 pFramePacking->frame0_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 4);
536 pFramePacking->frame1_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 8);
537 pFramePacking->frame1_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 12);
545 * [Decoder OPS] Enable Decode waiting for share Mode,
546 * to make sure destination support is completed and
547 * reset when Destination streamoff
549 static ExynosVideoErrorType MFC_Decoder_Enable_DecodeWait(void *pHandle)
551 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
552 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
553 #ifdef V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START
555 ALOGE("%s: Video context info must be supplied", __func__);
556 ret = VIDEO_ERROR_BADPARAM;
560 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START, 1) != 0) {
561 ret = VIDEO_ERROR_APIFAIL;
570 * [Decoder Buffer OPS] Enable Cacheable (Input)
572 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Inbuf(void *pHandle)
574 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
575 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
578 ALOGE("%s: Video context info must be supplied", __func__);
579 ret = VIDEO_ERROR_BADPARAM;
582 #ifdef V4L2_CID_CACHEABLE
583 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 2) != 0) {
584 ret = VIDEO_ERROR_APIFAIL;
593 * [Decoder Buffer OPS] Enable Cacheable (Output)
595 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Outbuf(void *pHandle)
597 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
598 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
601 ALOGE("%s: Video context info must be supplied", __func__);
602 ret = VIDEO_ERROR_BADPARAM;
605 #ifdef V4L2_CID_CACHEABLE
606 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 1) != 0) {
607 ret = VIDEO_ERROR_APIFAIL;
616 * [Decoder Buffer OPS] Set Shareable Buffer (Input)
618 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Inbuf(void *pHandle)
620 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
621 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
624 ALOGE("%s: Video context info must be supplied", __func__);
625 ret = VIDEO_ERROR_BADPARAM;
629 pCtx->bShareInbuf = VIDEO_TRUE;
636 * [Decoder Buffer OPS] Set Shareable Buffer (Output)
638 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Outbuf(void *pHandle)
640 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
641 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
644 ALOGE("%s: Video context info must be supplied", __func__);
645 ret = VIDEO_ERROR_BADPARAM;
649 pCtx->bShareOutbuf = VIDEO_TRUE;
656 * [Decoder Buffer OPS] Get Buffer (Input)
658 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Inbuf(
661 ExynosVideoBuffer **pBuffer)
663 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
664 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
667 ALOGE("%s: Video context info must be supplied", __func__);
669 ret = VIDEO_ERROR_BADPARAM;
673 if (pCtx->nInbufs <= nIndex) {
675 ret = VIDEO_ERROR_BADPARAM;
679 *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex];
686 * [Decoder Buffer OPS] Get Buffer (Output)
688 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Outbuf(
691 ExynosVideoBuffer **pBuffer)
693 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
694 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
697 ALOGE("%s: Video context info must be supplied", __func__);
699 ret = VIDEO_ERROR_BADPARAM;
703 if (pCtx->nOutbufs <= nIndex) {
705 ret = VIDEO_ERROR_BADPARAM;
709 *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex];
716 * [Decoder Buffer OPS] Set Geometry (Input)
718 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Inbuf(
720 ExynosVideoGeometry *bufferConf)
722 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
723 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
725 struct v4l2_format fmt;
728 ALOGE("%s: Video context info must be supplied", __func__);
729 ret = VIDEO_ERROR_BADPARAM;
733 if (bufferConf == NULL) {
734 ALOGE("%s: Buffer geometry must be supplied", __func__);
735 ret = VIDEO_ERROR_BADPARAM;
739 memset(&fmt, 0, sizeof(fmt));
741 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
742 fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat);
743 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage;
745 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) {
746 ret = VIDEO_ERROR_APIFAIL;
750 memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry));
757 * [Decoder Buffer OPS] Set Geometry (Output)
759 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Outbuf(
761 ExynosVideoGeometry *bufferConf)
763 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
764 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
766 struct v4l2_format fmt;
769 ALOGE("%s: Video context info must be supplied", __func__);
770 ret = VIDEO_ERROR_BADPARAM;
774 if (bufferConf == NULL) {
775 ALOGE("%s: Buffer geometry must be supplied", __func__);
776 ret = VIDEO_ERROR_BADPARAM;
780 memset(&fmt, 0, sizeof(fmt));
782 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
783 fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat);
785 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) {
786 ret = VIDEO_ERROR_APIFAIL;
790 memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry));
797 * [Decoder Buffer OPS] Get Geometry (Output)
799 static ExynosVideoErrorType MFC_Decoder_Get_Geometry_Outbuf(
801 ExynosVideoGeometry *bufferConf)
803 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
804 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
806 struct v4l2_format fmt;
807 struct v4l2_crop crop;
810 ALOGE("%s: Video context info must be supplied", __func__);
811 ret = VIDEO_ERROR_BADPARAM;
815 if (bufferConf == NULL) {
816 ALOGE("%s: Buffer geometry must be supplied", __func__);
817 ret = VIDEO_ERROR_BADPARAM;
821 memset(&fmt, 0, sizeof(fmt));
822 memset(&crop, 0, sizeof(crop));
824 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
826 if (exynos_v4l2_g_fmt(pCtx->hDec, &fmt) != 0) {
827 ALOGE("%s: exynos_v4l2_g_fmt. ret = %d", __func__, ret);
828 ret = VIDEO_ERROR_APIFAIL;
832 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
834 if (exynos_v4l2_g_crop(pCtx->hDec, &crop) != 0) {
835 ALOGE("%s: exynos_v4l2_g_crop. ret=%d", __func__, ret);
836 ret = VIDEO_ERROR_APIFAIL;
840 bufferConf->nFrameWidth = fmt.fmt.pix_mp.width;
841 bufferConf->nFrameHeight = fmt.fmt.pix_mp.height;
843 bufferConf->cropRect.nTop = crop.c.top;
844 bufferConf->cropRect.nLeft = crop.c.left;
845 bufferConf->cropRect.nWidth = crop.c.width;
846 bufferConf->cropRect.nHeight = crop.c.height;
853 * [Decoder Buffer OPS] Setup (Input)
855 static ExynosVideoErrorType MFC_Decoder_Setup_Inbuf(
857 unsigned int nBufferCount)
859 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
860 ExynosVideoPlane *pVideoPlane = NULL;
861 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
863 struct v4l2_requestbuffers req;
864 struct v4l2_buffer buf;
865 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES];
869 ALOGE("%s: Video context info must be supplied", __func__);
870 ret = VIDEO_ERROR_BADPARAM;
874 if (nBufferCount == 0) {
875 ALOGE("%s: Buffer count must be greater than 0", __func__);
876 ret = VIDEO_ERROR_BADPARAM;
880 ALOGV("%s: setting up inbufs (%d) shared=%s\n", __func__, nBufferCount,
881 pCtx->bShareInbuf ? "true" : "false");
883 memset(&req, 0, sizeof(req));
885 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
886 req.count = nBufferCount;
888 if (pCtx->bShareInbuf == VIDEO_TRUE)
889 req.memory = pCtx->nMemoryType;
891 req.memory = V4L2_MEMORY_MMAP;
893 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
894 ret = VIDEO_ERROR_APIFAIL;
898 if (req.count != nBufferCount) {
899 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count);
900 ret = VIDEO_ERROR_NOMEM;
904 pCtx->nInbufs = (int)req.count;
906 pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
907 if (pCtx->pInbuf == NULL) {
908 ALOGE("Failed to allocate input buffer context");
909 ret = VIDEO_ERROR_NOMEM;
912 memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
914 memset(&buf, 0, sizeof(buf));
916 if (pCtx->bShareInbuf == VIDEO_FALSE) {
917 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
918 buf.memory = V4L2_MEMORY_MMAP;
919 buf.m.planes = planes;
920 buf.length = VIDEO_DECODER_INBUF_PLANES;
922 ALOGV("[%s] INBUF V4L2_MEMORY_MMAP", __func__);
923 for (i = 0; i < pCtx->nInbufs; i++) {
925 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) {
926 ret = VIDEO_ERROR_APIFAIL;
930 pVideoPlane = &pCtx->pInbuf[i].planes[0];
932 pVideoPlane->addr = mmap(NULL,
933 buf.m.planes[0].length, PROT_READ | PROT_WRITE,
934 MAP_SHARED, pCtx->hDec, buf.m.planes[0].m.mem_offset);
936 if (pVideoPlane->addr == MAP_FAILED) {
937 ret = VIDEO_ERROR_MAPFAIL;
941 pVideoPlane->allocSize = buf.m.planes[0].length;
942 pVideoPlane->dataSize = 0;
944 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
945 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
946 pCtx->pInbuf[i].bRegistered = VIDEO_TRUE;
953 if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) {
954 if (pCtx->bShareInbuf == VIDEO_FALSE) {
955 for (i = 0; i < pCtx->nInbufs; i++) {
956 pVideoPlane = &pCtx->pInbuf[i].planes[0];
957 if (pVideoPlane->addr == MAP_FAILED) {
958 pVideoPlane->addr = NULL;
962 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
973 * [Decoder Buffer OPS] Setup (Output)
975 static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf(
977 unsigned int nBufferCount)
979 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
980 ExynosVideoPlane *pVideoPlane = NULL;
981 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
983 struct v4l2_requestbuffers req;
984 struct v4l2_buffer buf;
985 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES];
989 ALOGE("%s: Video context info must be supplied", __func__);
990 ret = VIDEO_ERROR_BADPARAM;
994 if (nBufferCount == 0) {
995 ALOGE("%s: Buffer count must be greater than 0", __func__);
996 ret = VIDEO_ERROR_BADPARAM;
1000 ALOGV("%s: setting up outbufs (%d) shared=%s\n", __func__, nBufferCount,
1001 pCtx->bShareOutbuf ? "true" : "false");
1003 memset(&req, 0, sizeof(req));
1005 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1006 req.count = nBufferCount;
1008 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1009 req.memory = pCtx->nMemoryType;
1011 req.memory = V4L2_MEMORY_MMAP;
1013 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1014 ret = VIDEO_ERROR_APIFAIL;
1018 if (req.count != nBufferCount) {
1019 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count);
1020 ret = VIDEO_ERROR_NOMEM;
1024 pCtx->nOutbufs = req.count;
1026 pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1027 if (pCtx->pOutbuf == NULL) {
1028 ALOGE("Failed to allocate output buffer context");
1029 ret = VIDEO_ERROR_NOMEM;
1032 memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1034 memset(&buf, 0, sizeof(buf));
1036 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1037 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1038 buf.memory = V4L2_MEMORY_MMAP;
1039 buf.m.planes = planes;
1040 buf.length = VIDEO_DECODER_OUTBUF_PLANES;
1042 ALOGV("[%s] OUTBUF V4L2_MEMORY_MMAP", __func__);
1043 for (i = 0; i < pCtx->nOutbufs; i++) {
1045 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) {
1046 ret = VIDEO_ERROR_APIFAIL;
1050 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1051 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1052 pVideoPlane->addr = mmap(NULL,
1053 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1054 MAP_SHARED, pCtx->hDec, buf.m.planes[j].m.mem_offset);
1056 if (pVideoPlane->addr == MAP_FAILED) {
1057 ret = VIDEO_ERROR_MAPFAIL;
1061 pVideoPlane->allocSize = buf.m.planes[j].length;
1062 pVideoPlane->dataSize = 0;
1064 #ifdef TIZEN_FEATURE_E3250 /* dmabuf */
1066 if (pCtx->bufShareMethod == BUF_SHARE_FD) {
1067 exynos_v4l2_expbuf(pCtx->hDec, &pVideoPlane->fd, buf.m.planes[j].m.mem_offset);
1068 ALOGV("[%s] fd (%d) received from MFC", __func__, pVideoPlane->fd);
1074 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1075 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1076 pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE;
1083 if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) {
1084 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1085 for (i = 0; i < pCtx->nOutbufs; i++) {
1086 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1087 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1088 if (pVideoPlane->addr == MAP_FAILED) {
1089 pVideoPlane->addr = NULL;
1093 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1098 free(pCtx->pOutbuf);
1105 * [Decoder Buffer OPS] Run (Input)
1107 static ExynosVideoErrorType MFC_Decoder_Run_Inbuf(void *pHandle)
1109 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1110 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1113 ALOGE("%s: Video context info must be supplied", __func__);
1114 ret = VIDEO_ERROR_BADPARAM;
1118 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1119 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1120 ALOGE("%s: Failed to streamon for input buffer", __func__);
1121 ret = VIDEO_ERROR_APIFAIL;
1124 pCtx->bStreamonInbuf = VIDEO_TRUE;
1132 * [Decoder Buffer OPS] Run (Output)
1134 static ExynosVideoErrorType MFC_Decoder_Run_Outbuf(void *pHandle)
1136 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1137 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1140 ALOGE("%s: Video context info must be supplied", __func__);
1141 ret = VIDEO_ERROR_BADPARAM;
1145 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1146 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1147 ALOGE("%s: Failed to streamon for output buffer", __func__);
1148 ret = VIDEO_ERROR_APIFAIL;
1151 pCtx->bStreamonOutbuf = VIDEO_TRUE;
1159 * [Decoder Buffer OPS] Stop (Input)
1161 static ExynosVideoErrorType MFC_Decoder_Stop_Inbuf(void *pHandle)
1163 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1164 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1168 ALOGE("%s: Video context info must be supplied", __func__);
1169 ret = VIDEO_ERROR_BADPARAM;
1173 if (pCtx->bStreamonInbuf == VIDEO_TRUE) {
1174 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1175 ALOGE("%s: Failed to streamoff for input buffer", __func__);
1176 ret = VIDEO_ERROR_APIFAIL;
1179 pCtx->bStreamonInbuf = VIDEO_FALSE;
1182 for (i = 0; i < pCtx->nInbufs; i++) {
1183 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1191 * [Decoder Buffer OPS] Stop (Output)
1193 static ExynosVideoErrorType MFC_Decoder_Stop_Outbuf(void *pHandle)
1195 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1196 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1200 ALOGE("%s: Video context info must be supplied", __func__);
1201 ret = VIDEO_ERROR_BADPARAM;
1205 if (pCtx->bStreamonOutbuf == VIDEO_TRUE) {
1206 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1207 ALOGE("%s: Failed to streamoff for output buffer", __func__);
1208 ret = VIDEO_ERROR_APIFAIL;
1211 pCtx->bStreamonOutbuf = VIDEO_FALSE;
1214 for (i = 0; i < pCtx->nOutbufs; i++) {
1215 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1224 * [Decoder Buffer OPS] Wait (Input)
1226 static ExynosVideoErrorType MFC_Decoder_Wait_Inbuf(void *pHandle)
1228 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1229 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1231 struct pollfd poll_events;
1235 ALOGE("%s: Video context info must be supplied", __func__);
1236 ret = VIDEO_ERROR_BADPARAM;
1240 poll_events.fd = pCtx->hDec;
1241 poll_events.events = POLLOUT | POLLERR;
1242 poll_events.revents = 0;
1245 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_DECODER_POLL_TIMEOUT);
1246 if (poll_state > 0) {
1247 if (poll_events.revents & POLLOUT) {
1250 ALOGE("%s: Poll return error", __func__);
1251 ret = VIDEO_ERROR_POLL;
1254 } else if (poll_state < 0) {
1255 ALOGE("%s: Poll state error", __func__);
1256 ret = VIDEO_ERROR_POLL;
1259 } while (poll_state == 0);
1266 static ExynosVideoErrorType MFC_Decoder_Register_Inbuf(
1268 ExynosVideoPlane *planes,
1271 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1272 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1275 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_INBUF_PLANES)) {
1276 ALOGE("%s: params must be supplied", __func__);
1277 ret = VIDEO_ERROR_BADPARAM;
1281 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1282 if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) {
1283 for (plane = 0; plane < nPlanes; plane++) {
1284 pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr;
1285 pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1286 pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd;
1287 ALOGV("%s: registered buf %d (addr=%p alloc_sz=%ld fd=%d)\n", __func__, nIndex,
1288 planes[plane].addr, planes[plane].allocSize, planes[plane].fd);
1290 pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE;
1295 if (nIndex == pCtx->nInbufs) {
1296 ALOGE("%s: can not find non-registered input buffer", __func__);
1297 ret = VIDEO_ERROR_NOBUFFERS;
1304 static ExynosVideoErrorType MFC_Decoder_Register_Outbuf(
1306 ExynosVideoPlane *planes,
1309 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1310 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1313 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_OUTBUF_PLANES)) {
1314 ALOGE("%s: params must be supplied", __func__);
1315 ret = VIDEO_ERROR_BADPARAM;
1319 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1320 if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) {
1321 for (plane = 0; plane < nPlanes; plane++) {
1322 pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr;
1323 pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1324 pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd;
1325 pCtx->pOutbuf[nIndex].planes[plane].tbm_bo = planes[plane].tbm_bo;
1327 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE;
1328 ALOGV("%s: registered buf %d 0:(addr=%p alloc_sz=%d fd=%d) 1:(addr=%p alloc_sz=%d fd=%d)\n",
1329 __func__, nIndex, planes[0].addr, planes[0].allocSize, planes[0].fd,
1330 planes[1].addr, planes[1].allocSize, planes[1].fd);
1335 if (nIndex == pCtx->nOutbufs) {
1336 ALOGE("%s: can not find non-registered output buffer", __func__);
1337 ret = VIDEO_ERROR_NOBUFFERS;
1344 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
1346 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1347 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1351 ALOGE("%s: Video context info must be supplied", __func__);
1352 ret = VIDEO_ERROR_BADPARAM;
1356 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1357 pCtx->pInbuf[nIndex].planes[0].addr = NULL;
1358 pCtx->pInbuf[nIndex].planes[0].fd = -1;
1359 pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE;
1366 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
1368 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1369 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1373 ALOGE("%s: Video context info must be supplied", __func__);
1374 ret = VIDEO_ERROR_BADPARAM;
1378 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1379 pCtx->pOutbuf[nIndex].planes[0].addr = NULL;
1380 pCtx->pOutbuf[nIndex].planes[0].fd = -1;
1381 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE;
1389 * [Decoder Buffer OPS] Find (Input)
1391 static int MFC_Decoder_Find_Inbuf(
1393 unsigned char *pBuffer)
1395 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1399 ALOGE("%s: Video context info must be supplied", __func__);
1403 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1404 if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) {
1405 if ((pBuffer == NULL) ||
1406 (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer))
1411 if (nIndex == pCtx->nInbufs)
1419 * [Decoder Buffer OPS] Find (Outnput)
1421 static int MFC_Decoder_Find_Outbuf(
1423 unsigned char *pBuffer)
1425 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1429 ALOGE("%s: Video context info must be supplied", __func__);
1433 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1434 if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) {
1435 if ((pBuffer == NULL) ||
1436 (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer))
1441 if (nIndex == pCtx->nOutbufs)
1449 * [Decoder Buffer OPS] Enqueue (Input)
1451 static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf(
1453 unsigned char *pBuffer[],
1454 unsigned int dataSize[],
1458 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1459 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1460 pthread_mutex_t *pMutex = NULL;
1462 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES];
1463 struct v4l2_buffer buf;
1467 ALOGE("%s: Video context info must be supplied", __func__);
1468 ret = VIDEO_ERROR_BADPARAM;
1472 if (VIDEO_DECODER_INBUF_PLANES < nPlanes) {
1473 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1474 VIDEO_DECODER_INBUF_PLANES, nPlanes);
1475 ret = VIDEO_ERROR_BADPARAM;
1479 memset(&buf, 0, sizeof(buf));
1481 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1482 buf.m.planes = planes;
1483 buf.length = VIDEO_DECODER_INBUF_PLANES;
1485 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
1486 pthread_mutex_lock(pMutex);
1487 index = MFC_Decoder_Find_Inbuf(pCtx, pBuffer[0]);
1489 pthread_mutex_unlock(pMutex);
1490 ALOGE("%s: Failed to get index", __func__);
1491 ret = VIDEO_ERROR_NOBUFFERS;
1496 pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE;
1497 pthread_mutex_unlock(pMutex);
1499 if (pCtx->bShareInbuf == VIDEO_TRUE) {
1500 buf.memory = pCtx->nMemoryType;
1501 for (i = 0; i < nPlanes; i++) {
1502 /* V4L2_MEMORY_USERPTR */
1503 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1504 /* V4L2_MEMORY_DMABUF */
1506 buf.m.planes[i].m.fd = pCtx->pInbuf[index].planes[i].fd;
1508 buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize;
1509 buf.m.planes[i].bytesused = dataSize[i];
1510 ALOGV("%s: shared INBUF(%d) plane(%d) data_offset= %x addr=%p len=%d used=%d\n", __func__,
1512 buf.m.planes[i].data_offset,
1513 buf.m.planes[i].m.userptr,
1514 buf.m.planes[i].length,
1515 buf.m.planes[i].bytesused);
1518 buf.memory = V4L2_MEMORY_MMAP;
1519 for (i = 0; i < nPlanes; i++)
1520 buf.m.planes[i].bytesused = dataSize[i];
1523 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) {
1524 ALOGE("%s: Failed to enqueue input buffer", __func__);
1525 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1526 ret = VIDEO_ERROR_APIFAIL;
1530 pCtx->pInbuf[buf.index].pPrivate = pPrivate;
1537 * [Decoder Buffer OPS] Enqueue (Output)
1539 static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf(
1541 unsigned char *pBuffer[],
1542 unsigned int dataSize[],
1546 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1547 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1548 pthread_mutex_t *pMutex = NULL;
1550 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES];
1551 struct v4l2_buffer buf;
1555 ALOGE("%s: Video context info must be supplied", __func__);
1556 ret = VIDEO_ERROR_BADPARAM;
1560 if (VIDEO_DECODER_OUTBUF_PLANES < nPlanes) {
1561 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1562 VIDEO_DECODER_OUTBUF_PLANES, nPlanes);
1563 ret = VIDEO_ERROR_BADPARAM;
1567 memset(&buf, 0, sizeof(buf));
1569 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1570 buf.m.planes = planes;
1571 buf.length = VIDEO_DECODER_OUTBUF_PLANES;
1573 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
1574 pthread_mutex_lock(pMutex);
1575 index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]);
1577 pthread_mutex_unlock(pMutex);
1578 ALOGE("%s: Failed to get index", __func__);
1579 ret = VIDEO_ERROR_NOBUFFERS;
1583 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE;
1584 pthread_mutex_unlock(pMutex);
1586 if (pCtx->bShareOutbuf == VIDEO_TRUE) {
1587 buf.memory = pCtx->nMemoryType;
1588 for (i = 0; i < nPlanes; i++) {
1589 /* V4L2_MEMORY_USERPTR */
1590 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1591 /* V4L2_MEMORY_DMABUF */
1593 buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd;
1595 buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize;
1596 buf.m.planes[i].bytesused = dataSize[i];
1597 ALOGV("%s: shared OUTBUF(%d) plane=%d data_offset= %x addr=0x%lx len=%d used=%d\n", __func__,
1599 buf.m.planes[i].data_offset,
1600 buf.m.planes[i].m.userptr,
1601 buf.m.planes[i].length,
1602 buf.m.planes[i].bytesused);
1605 ALOGV("%s: non-shared outbuf(%d)\n", __func__, index);
1606 buf.memory = V4L2_MEMORY_MMAP;
1609 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) {
1610 ALOGE("%s: Failed to enqueue output buffer", __func__);
1611 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE;
1612 ret = VIDEO_ERROR_APIFAIL;
1616 pCtx->pOutbuf[buf.index].pPrivate = pPrivate;
1623 * [Decoder Buffer OPS] Dequeue (Input)
1625 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle)
1627 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1628 ExynosVideoBuffer *pInbuf = NULL;
1630 struct v4l2_buffer buf;
1633 ALOGE("%s: Video context info must be supplied", __func__);
1637 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1642 memset(&buf, 0, sizeof(buf));
1644 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1646 if (pCtx->bShareInbuf == VIDEO_TRUE)
1647 buf.memory = pCtx->nMemoryType;
1649 buf.memory = V4L2_MEMORY_MMAP;
1651 if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) {
1656 pInbuf = &pCtx->pInbuf[buf.index];
1657 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1659 if (pCtx->bStreamonInbuf == VIDEO_FALSE)
1667 * [Decoder Buffer OPS] Dequeue (Output)
1669 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle)
1671 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1672 ExynosVideoBuffer *pOutbuf = NULL;
1674 struct v4l2_buffer buf;
1680 ALOGE("%s: Video context info must be supplied", __func__);
1684 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1689 memset(&buf, 0, sizeof(buf));
1690 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1692 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1693 buf.memory = pCtx->nMemoryType;
1695 buf.memory = V4L2_MEMORY_MMAP;
1697 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
1698 ret = exynos_v4l2_dqbuf(pCtx->hDec, &buf);
1701 pOutbuf = (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO;
1707 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1712 pOutbuf = &pCtx->pOutbuf[buf.index];
1714 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS
1715 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value);
1717 ALOGV("%s: V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS value = %d", __func__, value);
1720 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY;
1723 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING;
1726 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY;
1729 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state);
1730 if (state == 1) /* Resolution change is detected */
1731 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
1732 else /* Decoding is finished */
1733 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED;
1736 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1740 switch (buf.flags & (0x7 << 3)) {
1742 case V4L2_BUF_FLAG_KEYFRAME:
1743 pOutbuf->frameType = VIDEO_FRAME_I;
1745 case V4L2_BUF_FLAG_PFRAME:
1746 pOutbuf->frameType = VIDEO_FRAME_P;
1748 case V4L2_BUF_FLAG_BFRAME:
1749 pOutbuf->frameType = VIDEO_FRAME_B;
1752 pOutbuf->frameType = VIDEO_FRAME_OTHERS;
1756 pOutbuf->bQueued = VIDEO_FALSE;
1762 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Inbuf(void *pHandle)
1764 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1765 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1769 ALOGE("%s: Video context info must be supplied", __func__);
1770 ret = VIDEO_ERROR_BADPARAM;
1774 for (i = 0; i < pCtx->nInbufs; i++) {
1775 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1782 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Outbuf(void *pHandle)
1784 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1785 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1789 ALOGE("%s: Video context info must be supplied", __func__);
1790 ret = VIDEO_ERROR_BADPARAM;
1794 for (i = 0; i < pCtx->nOutbufs; i++) {
1795 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1802 /* [Decoder Buffer OPS] Cleanup (Input)
1804 static ExynosVideoErrorType MFC_Decoder_Cleanup_Inbuf(void *pHandle)
1806 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1807 ExynosVideoPlane *pVideoPlane = NULL;
1808 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1810 struct v4l2_requestbuffers req;
1811 int nBufferCount, i, j;
1814 ALOGE("%s: Video context info must be supplied", __func__);
1815 ret = VIDEO_ERROR_BADPARAM;
1819 nBufferCount = 0; /* for Clean-up */
1821 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1822 for (i = 0; i < pCtx->nInbufs; i++) {
1823 for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) {
1824 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1825 if (pVideoPlane->addr != NULL) {
1826 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1827 pVideoPlane->addr = NULL;
1828 pVideoPlane->allocSize = 0;
1829 pVideoPlane->dataSize = 0;
1832 pCtx->pInbuf[i].pGeometry = NULL;
1833 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1834 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
1839 memset(&req, 0, sizeof(req));
1841 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1842 req.count = nBufferCount;
1844 if (pCtx->bShareInbuf == VIDEO_TRUE)
1845 req.memory = pCtx->nMemoryType;
1847 req.memory = V4L2_MEMORY_MMAP;
1849 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1850 ret = VIDEO_ERROR_APIFAIL;
1854 pCtx->nInbufs = (int)req.count;
1856 if (pCtx->pInbuf != NULL)
1864 * [Decoder Buffer OPS] Cleanup (Output)
1866 static ExynosVideoErrorType MFC_Decoder_Cleanup_Outbuf(void *pHandle)
1868 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle;
1869 ExynosVideoPlane *pVideoPlane = NULL;
1870 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1872 struct v4l2_requestbuffers req;
1873 int nBufferCount, i ,j;
1876 ALOGE("%s: Video context info must be supplied", __func__);
1877 ret = VIDEO_ERROR_BADPARAM;
1881 nBufferCount = 0; /* for Clean-up */
1883 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1884 for (i = 0; i < pCtx->nOutbufs; i++) {
1885 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) {
1886 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1887 if (pVideoPlane->addr != NULL) {
1888 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1889 pVideoPlane->addr = NULL;
1890 pVideoPlane->allocSize = 0;
1891 pVideoPlane->dataSize = 0;
1894 pCtx->pOutbuf[i].pGeometry = NULL;
1895 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1896 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
1901 memset(&req, 0, sizeof(req));
1903 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1904 req.count = nBufferCount;
1906 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1907 req.memory = pCtx->nMemoryType;
1909 req.memory = V4L2_MEMORY_MMAP;
1911 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) {
1912 ALOGE("reqbuf fail");
1913 ret = VIDEO_ERROR_APIFAIL;
1917 pCtx->nOutbufs = req.count;
1919 if (pCtx->pOutbuf != NULL)
1920 free(pCtx->pOutbuf);
1927 * [Decoder OPS] Common
1929 static ExynosVideoDecOps defDecOps = {
1931 .Init = MFC_Decoder_Init,
1932 .Finalize = MFC_Decoder_Finalize,
1933 .Set_DisplayDelay = MFC_Decoder_Set_DisplayDelay,
1934 .Enable_PackedPB = MFC_Decoder_Enable_PackedPB,
1935 .Enable_LoopFilter = MFC_Decoder_Enable_LoopFilter,
1936 .Enable_SliceMode = MFC_Decoder_Enable_SliceMode,
1937 .Get_ActualBufferCount = MFC_Decoder_Get_ActualBufferCount,
1938 .Set_FrameTag = MFC_Decoder_Set_FrameTag,
1939 .Get_FrameTag = MFC_Decoder_Get_FrameTag,
1940 .Enable_SEIParsing = MFC_Decoder_Enable_SEIParsing,
1941 .Get_FramePackingInfo = MFC_Decoder_Get_FramePackingInfo,
1942 .Set_ImmediateDisplay = MFC_Decoder_Set_ImmediateDisplay,
1943 .Enable_DecodeWait = MFC_Decoder_Enable_DecodeWait,
1947 * [Decoder Buffer OPS] Input
1949 static ExynosVideoDecBufferOps defInbufOps = {
1951 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Inbuf,
1952 .Set_Shareable = MFC_Decoder_Set_Shareable_Inbuf,
1953 .Get_Buffer = MFC_Decoder_Get_Buffer_Inbuf,
1954 .Set_Geometry = MFC_Decoder_Set_Geometry_Inbuf,
1955 .Get_Geometry = NULL,
1956 .Setup = MFC_Decoder_Setup_Inbuf,
1957 .Run = MFC_Decoder_Run_Inbuf,
1958 .Stop = MFC_Decoder_Stop_Inbuf,
1959 .Enqueue = MFC_Decoder_Enqueue_Inbuf,
1960 .Enqueue_All = NULL,
1961 .Dequeue = MFC_Decoder_Dequeue_Inbuf,
1962 .Register = MFC_Decoder_Register_Inbuf,
1963 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Inbuf,
1964 .Clear_Queue = MFC_Decoder_Clear_Queued_Inbuf,
1965 .Cleanup = MFC_Decoder_Cleanup_Inbuf,
1969 * [Decoder Buffer OPS] Output
1971 static ExynosVideoDecBufferOps defOutbufOps = {
1973 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Outbuf,
1974 .Set_Shareable = MFC_Decoder_Set_Shareable_Outbuf,
1975 .Get_Buffer = MFC_Decoder_Get_Buffer_Outbuf,
1976 .Set_Geometry = MFC_Decoder_Set_Geometry_Outbuf,
1977 .Get_Geometry = MFC_Decoder_Get_Geometry_Outbuf,
1978 .Setup = MFC_Decoder_Setup_Outbuf,
1979 .Run = MFC_Decoder_Run_Outbuf,
1980 .Stop = MFC_Decoder_Stop_Outbuf,
1981 .Enqueue = MFC_Decoder_Enqueue_Outbuf,
1982 .Enqueue_All = NULL,
1983 .Dequeue = MFC_Decoder_Dequeue_Outbuf,
1984 .Register = MFC_Decoder_Register_Outbuf,
1985 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Outbuf,
1986 .Clear_Queue = MFC_Decoder_Clear_Queued_Outbuf,
1987 .Cleanup = MFC_Decoder_Cleanup_Outbuf,
1990 int Exynos_Video_Register_Decoder(
1991 ExynosVideoDecOps *pDecOps,
1992 ExynosVideoDecBufferOps *pInbufOps,
1993 ExynosVideoDecBufferOps *pOutbufOps)
1995 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1997 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
1998 ret = VIDEO_ERROR_BADPARAM;
2002 defDecOps.nSize = sizeof(defDecOps);
2003 defInbufOps.nSize = sizeof(defInbufOps);
2004 defOutbufOps.nSize = sizeof(defOutbufOps);
2006 memcpy((char *)pDecOps + sizeof(pDecOps->nSize), (char *)&defDecOps + sizeof(defDecOps.nSize),
2007 pDecOps->nSize - sizeof(pDecOps->nSize));
2009 memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
2010 pInbufOps->nSize - sizeof(pInbufOps->nSize));
2012 memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
2013 pOutbufOps->nSize - sizeof(pOutbufOps->nSize));