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
33 #include <sys/types.h>
35 #include <sys/ioctl.h>
42 #include "ExynosVideoApi.h"
43 #include "ExynosVideoDec.h"
46 /* #define LOG_NDEBUG 0 */
47 #define LOG_TAG "ExynosVideoDecoder"
48 #include <utils/Log.h>
50 #define MAX_OUTPUTBUFFER_COUNT 32
53 * [Common] __CodingType_To_V4L2PixelFormat
55 static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType
)
57 unsigned int pixelformat
= V4L2_PIX_FMT_H264
;
60 case VIDEO_CODING_AVC
:
61 pixelformat
= V4L2_PIX_FMT_H264
;
63 case VIDEO_CODING_MPEG4
:
64 pixelformat
= V4L2_PIX_FMT_MPEG4
;
66 case VIDEO_CODING_VP8
:
67 pixelformat
= V4L2_PIX_FMT_VP8
;
69 case VIDEO_CODING_H263
:
70 pixelformat
= V4L2_PIX_FMT_H263
;
72 case VIDEO_CODING_VC1
:
73 pixelformat
= V4L2_PIX_FMT_VC1_ANNEX_G
;
75 case VIDEO_CODING_VC1_RCV
:
76 pixelformat
= V4L2_PIX_FMT_VC1_ANNEX_L
;
78 case VIDEO_CODING_MPEG2
:
79 pixelformat
= V4L2_PIX_FMT_MPEG2
;
82 pixelformat
= V4L2_PIX_FMT_H264
;
90 * [Common] __ColorFormatType_To_V4L2PixelFormat
92 static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType
)
94 unsigned int pixelformat
= V4L2_PIX_FMT_NV12M
;
96 switch (colorFormatType
) {
97 case VIDEO_COLORFORMAT_NV12_TILED
:
98 pixelformat
= V4L2_PIX_FMT_NV12MT_16X16
;
100 case VIDEO_COLORFORMAT_NV21
:
101 pixelformat
= V4L2_PIX_FMT_NV21M
;
103 case VIDEO_COLORFORMAT_NV12
:
105 pixelformat
= V4L2_PIX_FMT_NV12M
;
115 static void *MFC_Decoder_Init(int nMemoryType
)
117 ExynosVideoDecContext
*pCtx
= NULL
;
118 pthread_mutex_t
*pMutex
= NULL
;
119 int needCaps
= (V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_VIDEO_OUTPUT
| V4L2_CAP_STREAMING
);
121 pCtx
= (ExynosVideoDecContext
*)malloc(sizeof(*pCtx
));
123 ALOGE("%s: Failed to allocate decoder context buffer", __func__
);
124 goto EXIT_ALLOC_FAIL
;
127 memset(pCtx
, 0, sizeof(*pCtx
));
129 pCtx
->hDec
= exynos_v4l2_open_devname(VIDEO_DECODER_NAME
, O_RDWR
, 0);
130 if (pCtx
->hDec
< 0) {
131 ALOGE("%s: Failed to open decoder device", __func__
);
135 if (!exynos_v4l2_querycap(pCtx
->hDec
, needCaps
)) {
136 ALOGE("%s: Failed to querycap", __func__
);
137 goto EXIT_QUERYCAP_FAIL
;
140 pCtx
->bStreamonInbuf
= VIDEO_FALSE
;
141 pCtx
->bStreamonOutbuf
= VIDEO_FALSE
;
143 pCtx
->nMemoryType
= nMemoryType
;
145 pMutex
= (pthread_mutex_t
*)malloc(sizeof(pthread_mutex_t
));
146 if (pMutex
== NULL
) {
147 ALOGE("%s: Failed to allocate mutex about input buffer", __func__
);
148 goto EXIT_QUERYCAP_FAIL
;
150 if (pthread_mutex_init(pMutex
, NULL
) != 0) {
152 goto EXIT_QUERYCAP_FAIL
;
154 pCtx
->pInMutex
= (void*)pMutex
;
156 pMutex
= (pthread_mutex_t
*)malloc(sizeof(pthread_mutex_t
));
157 if (pMutex
== NULL
) {
158 ALOGE("%s: Failed to allocate mutex about output buffer", __func__
);
159 goto EXIT_QUERYCAP_FAIL
;
161 if (pthread_mutex_init(pMutex
, NULL
) != 0) {
163 goto EXIT_QUERYCAP_FAIL
;
165 pCtx
->pOutMutex
= (void*)pMutex
;
167 pCtx
->hIONHandle
= (void*)ion_client_create();
168 pCtx
->nPrivateDataShareFD
= ion_alloc((ion_client
)pCtx
->hIONHandle
,
169 sizeof(PrivateDataShareBuffer
) * VIDEO_BUFFER_MAX_NUM
, 0, ION_HEAP_SYSTEM_MASK
, ION_FLAG_CACHED
);
170 pCtx
->nPrivateDataShareAddress
=
171 ion_map(pCtx
->nPrivateDataShareFD
, sizeof(PrivateDataShareBuffer
) * VIDEO_BUFFER_MAX_NUM
, 0);
172 memset(pCtx
->nPrivateDataShareAddress
, -1, sizeof(PrivateDataShareBuffer
) * VIDEO_BUFFER_MAX_NUM
);
177 if (pCtx
->pInMutex
!= NULL
) {
178 pthread_mutex_destroy(pCtx
->pInMutex
);
179 free(pCtx
->pInMutex
);
182 if (pCtx
->pOutMutex
!= NULL
) {
183 pthread_mutex_destroy(pCtx
->pOutMutex
);
184 free(pCtx
->pOutMutex
);
197 * [Decoder OPS] Finalize
199 static ExynosVideoErrorType
MFC_Decoder_Finalize(void *pHandle
)
201 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
202 ExynosVideoPlane
*pVideoPlane
= NULL
;
203 pthread_mutex_t
*pMutex
= NULL
;
204 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
208 ALOGE("%s: Video context info must be supplied", __func__
);
209 ret
= VIDEO_ERROR_BADPARAM
;
213 ion_unmap(pCtx
->nPrivateDataShareAddress
, sizeof(PrivateDataShareBuffer
) * VIDEO_BUFFER_MAX_NUM
);
214 ion_free(pCtx
->nPrivateDataShareFD
);
215 ion_client_destroy((ion_client
)pCtx
->hIONHandle
);
217 if (pCtx
->pOutMutex
!= NULL
) {
218 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
219 pthread_mutex_destroy(pMutex
);
221 pCtx
->pOutMutex
= NULL
;
224 if (pCtx
->pInMutex
!= NULL
) {
225 pMutex
= (pthread_mutex_t
*)pCtx
->pInMutex
;
226 pthread_mutex_destroy(pMutex
);
228 pCtx
->pInMutex
= NULL
;
231 if (pCtx
->bShareInbuf
== VIDEO_FALSE
) {
232 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
233 for (j
= 0; j
< VIDEO_DECODER_INBUF_PLANES
; j
++) {
234 pVideoPlane
= &pCtx
->pInbuf
[i
].planes
[j
];
235 if (pVideoPlane
->addr
!= NULL
) {
236 munmap(pVideoPlane
->addr
, pVideoPlane
->allocSize
);
237 pVideoPlane
->addr
= NULL
;
238 pVideoPlane
->allocSize
= 0;
239 pVideoPlane
->dataSize
= 0;
242 pCtx
->pInbuf
[i
].pGeometry
= NULL
;
243 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
244 pCtx
->pInbuf
[i
].bRegistered
= VIDEO_FALSE
;
249 if (pCtx
->bShareOutbuf
== VIDEO_FALSE
) {
250 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
251 for (j
= 0; j
< VIDEO_DECODER_OUTBUF_PLANES
; j
++) {
252 pVideoPlane
= &pCtx
->pOutbuf
[i
].planes
[j
];
253 if (pVideoPlane
->addr
!= NULL
) {
254 munmap(pVideoPlane
->addr
, pVideoPlane
->allocSize
);
255 pVideoPlane
->addr
= NULL
;
256 pVideoPlane
->allocSize
= 0;
257 pVideoPlane
->dataSize
= 0;
260 pCtx
->pOutbuf
[i
].pGeometry
= NULL
;
261 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
262 pCtx
->pOutbuf
[i
].bRegistered
= VIDEO_FALSE
;
267 if (pCtx
->pInbuf
!= NULL
)
270 if (pCtx
->pOutbuf
!= NULL
)
283 * [Decoder OPS] Set Frame Tag
285 static ExynosVideoErrorType
MFC_Decoder_Set_FrameTag(
289 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
290 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
293 ALOGE("%s: Video context info must be supplied", __func__
);
294 ret
= VIDEO_ERROR_BADPARAM
;
298 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
, frameTag
) != 0) {
299 ret
= VIDEO_ERROR_APIFAIL
;
308 * [Decoder OPS] Get Frame Tag
310 static int MFC_Decoder_Get_FrameTag(void *pHandle
)
312 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
316 ALOGE("%s: Video context info must be supplied", __func__
);
320 exynos_v4l2_g_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
, &frameTag
);
327 * [Decoder OPS] Get Buffer Count
329 static int MFC_Decoder_Get_ActualBufferCount(void *pHandle
)
331 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
332 int bufferCount
= -1;
335 ALOGE("%s: Video context info must be supplied", __func__
);
339 exynos_v4l2_g_ctrl(pCtx
->hDec
, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE
, &bufferCount
);
346 * [Decoder OPS] Set Display Delay
348 static ExynosVideoErrorType
MFC_Decoder_Set_DisplayDelay(
352 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
353 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
356 ALOGE("%s: Video context info must be supplied", __func__
);
357 ret
= VIDEO_ERROR_BADPARAM
;
361 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY
, delay
) != 0) {
362 ret
= VIDEO_ERROR_APIFAIL
;
371 * [Decoder OPS] Set I-Frame Decoding
373 static ExynosVideoErrorType
MFC_Decoder_Set_IFrameDecoding(
376 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
377 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
380 ALOGE("%s: Video context info must be supplied", __func__
);
381 ret
= VIDEO_ERROR_BADPARAM
;
385 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_I_FRAME_DECODING
, 1) != 0) {
386 ret
= VIDEO_ERROR_APIFAIL
;
395 * [Decoder OPS] Enable Packed PB
397 static ExynosVideoErrorType
MFC_Decoder_Enable_PackedPB(void *pHandle
)
399 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
400 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
403 ALOGE("%s: Video context info must be supplied", __func__
);
404 ret
= VIDEO_ERROR_BADPARAM
;
408 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB
, 1) != 0) {
409 ret
= VIDEO_ERROR_APIFAIL
;
418 * [Decoder OPS] Enable Loop Filter
420 static ExynosVideoErrorType
MFC_Decoder_Enable_LoopFilter(void *pHandle
)
422 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
423 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
426 ALOGE("%s: Video context info must be supplied", __func__
);
427 ret
= VIDEO_ERROR_BADPARAM
;
431 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER
, 1) != 0) {
432 ret
= VIDEO_ERROR_APIFAIL
;
441 * [Decoder OPS] Enable Slice Mode
443 static ExynosVideoErrorType
MFC_Decoder_Enable_SliceMode(void *pHandle
)
445 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
446 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
449 ALOGE("%s: Video context info must be supplied", __func__
);
450 ret
= VIDEO_ERROR_BADPARAM
;
454 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE
, 1) != 0) {
455 ret
= VIDEO_ERROR_APIFAIL
;
464 * [Decoder OPS] Enable SEI Parsing
466 static ExynosVideoErrorType
MFC_Decoder_Enable_SEIParsing(void *pHandle
)
468 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
469 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
472 ALOGE("%s: Video context info must be supplied", __func__
);
473 ret
= VIDEO_ERROR_BADPARAM
;
477 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING
, 1) != 0) {
478 ret
= VIDEO_ERROR_APIFAIL
;
487 * [Decoder OPS] Get Frame Packing information
489 static ExynosVideoErrorType
MFC_Decoder_Get_FramePackingInfo(
491 ExynosVideoFramePacking
*pFramePacking
)
493 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
494 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
496 struct v4l2_ext_control ext_ctrl
[FRAME_PACK_SEI_INFO_NUM
];
497 struct v4l2_ext_controls ext_ctrls
;
499 int seiAvailable
, seiInfo
, seiGridPos
, i
;
500 unsigned int seiArgmtId
;
503 if ((pCtx
== NULL
) || (pFramePacking
== NULL
)) {
504 ALOGE("%s: Video context info or FramePacking pointer must be supplied", __func__
);
505 ret
= VIDEO_ERROR_BADPARAM
;
509 memset(pFramePacking
, 0, sizeof(*pFramePacking
));
510 memset(ext_ctrl
, 0, (sizeof(struct v4l2_ext_control
) * FRAME_PACK_SEI_INFO_NUM
));
512 ext_ctrls
.ctrl_class
= V4L2_CTRL_CLASS_MPEG
;
513 ext_ctrls
.count
= FRAME_PACK_SEI_INFO_NUM
;
514 ext_ctrls
.controls
= ext_ctrl
;
515 ext_ctrl
[0].id
= V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL
;
516 ext_ctrl
[1].id
= V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID
;
517 ext_ctrl
[2].id
= V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO
;
518 ext_ctrl
[3].id
= V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS
;
520 if (exynos_v4l2_g_ext_ctrl(pCtx
->hDec
, &ext_ctrls
) != 0) {
521 ret
= VIDEO_ERROR_APIFAIL
;
525 seiAvailable
= ext_ctrl
[0].value
;
526 seiArgmtId
= ext_ctrl
[1].value
;
527 seiInfo
= ext_ctrl
[2].value
;
528 seiGridPos
= ext_ctrl
[3].value
;
530 pFramePacking
->available
= seiAvailable
;
531 pFramePacking
->arrangement_id
= seiArgmtId
;
533 pFramePacking
->arrangement_cancel_flag
= OPERATE_BIT(seiInfo
, 0x1, 0);
534 pFramePacking
->arrangement_type
= OPERATE_BIT(seiInfo
, 0x3f, 1);
535 pFramePacking
->quincunx_sampling_flag
= OPERATE_BIT(seiInfo
, 0x1, 8);
536 pFramePacking
->content_interpretation_type
= OPERATE_BIT(seiInfo
, 0x3f, 9);
537 pFramePacking
->spatial_flipping_flag
= OPERATE_BIT(seiInfo
, 0x1, 15);
538 pFramePacking
->frame0_flipped_flag
= OPERATE_BIT(seiInfo
, 0x1, 16);
539 pFramePacking
->field_views_flag
= OPERATE_BIT(seiInfo
, 0x1, 17);
540 pFramePacking
->current_frame_is_frame0_flag
= OPERATE_BIT(seiInfo
, 0x1, 18);
542 pFramePacking
->frame0_grid_pos_x
= OPERATE_BIT(seiGridPos
, 0xf, 0);
543 pFramePacking
->frame0_grid_pos_y
= OPERATE_BIT(seiGridPos
, 0xf, 4);
544 pFramePacking
->frame1_grid_pos_x
= OPERATE_BIT(seiGridPos
, 0xf, 8);
545 pFramePacking
->frame1_grid_pos_y
= OPERATE_BIT(seiGridPos
, 0xf, 12);
552 * [Decoder Buffer OPS] Enable Cacheable (Input)
554 static ExynosVideoErrorType
MFC_Decoder_Enable_Cacheable_Inbuf(void *pHandle
)
556 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
557 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
560 ALOGE("%s: Video context info must be supplied", __func__
);
561 ret
= VIDEO_ERROR_BADPARAM
;
565 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_CACHEABLE
, 2) != 0) {
566 ret
= VIDEO_ERROR_APIFAIL
;
575 * [Decoder Buffer OPS] Enable Cacheable (Output)
577 static ExynosVideoErrorType
MFC_Decoder_Enable_Cacheable_Outbuf(void *pHandle
)
579 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
580 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
583 ALOGE("%s: Video context info must be supplied", __func__
);
584 ret
= VIDEO_ERROR_BADPARAM
;
588 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_CACHEABLE
, 1) != 0) {
589 ret
= VIDEO_ERROR_APIFAIL
;
598 * [Decoder Buffer OPS] Set Shareable Buffer (Input)
600 static ExynosVideoErrorType
MFC_Decoder_Set_Shareable_Inbuf(void *pHandle
)
602 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
603 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
606 ALOGE("%s: Video context info must be supplied", __func__
);
607 ret
= VIDEO_ERROR_BADPARAM
;
611 pCtx
->bShareInbuf
= VIDEO_TRUE
;
618 * [Decoder Buffer OPS] Set Shareable Buffer (Output)
620 static ExynosVideoErrorType
MFC_Decoder_Set_Shareable_Outbuf(void *pHandle
)
622 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
623 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
626 ALOGE("%s: Video context info must be supplied", __func__
);
627 ret
= VIDEO_ERROR_BADPARAM
;
631 pCtx
->bShareOutbuf
= VIDEO_TRUE
;
638 * [Decoder Buffer OPS] Get Buffer (Input)
640 static ExynosVideoErrorType
MFC_Decoder_Get_Buffer_Inbuf(
643 ExynosVideoBuffer
**pBuffer
)
645 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
646 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
649 ALOGE("%s: Video context info must be supplied", __func__
);
651 ret
= VIDEO_ERROR_BADPARAM
;
655 if (pCtx
->nInbufs
<= nIndex
) {
657 ret
= VIDEO_ERROR_BADPARAM
;
661 *pBuffer
= (ExynosVideoBuffer
*)&pCtx
->pInbuf
[nIndex
];
668 * [Decoder Buffer OPS] Get Buffer (Output)
670 static ExynosVideoErrorType
MFC_Decoder_Get_Buffer_Outbuf(
673 ExynosVideoBuffer
**pBuffer
)
675 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
676 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
679 ALOGE("%s: Video context info must be supplied", __func__
);
681 ret
= VIDEO_ERROR_BADPARAM
;
685 if (pCtx
->nOutbufs
<= nIndex
) {
687 ret
= VIDEO_ERROR_BADPARAM
;
691 *pBuffer
= (ExynosVideoBuffer
*)&pCtx
->pOutbuf
[nIndex
];
698 * [Decoder Buffer OPS] Set Geometry (Input)
700 static ExynosVideoErrorType
MFC_Decoder_Set_Geometry_Inbuf(
702 ExynosVideoGeometry
*bufferConf
)
704 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
705 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
707 struct v4l2_format fmt
;
710 ALOGE("%s: Video context info must be supplied", __func__
);
711 ret
= VIDEO_ERROR_BADPARAM
;
715 if (bufferConf
== NULL
) {
716 ALOGE("%s: Buffer geometry must be supplied", __func__
);
717 ret
= VIDEO_ERROR_BADPARAM
;
721 memset(&fmt
, 0, sizeof(fmt
));
723 fmt
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
724 fmt
.fmt
.pix_mp
.pixelformat
= __CodingType_To_V4L2PixelFormat(bufferConf
->eCompressionFormat
);
725 fmt
.fmt
.pix_mp
.plane_fmt
[0].sizeimage
= bufferConf
->nSizeImage
;
727 if (exynos_v4l2_s_fmt(pCtx
->hDec
, &fmt
) != 0) {
728 ret
= VIDEO_ERROR_APIFAIL
;
732 memcpy(&pCtx
->inbufGeometry
, bufferConf
, sizeof(pCtx
->inbufGeometry
));
739 * [Decoder Buffer OPS] Set Geometry (Output)
741 static ExynosVideoErrorType
MFC_Decoder_Set_Geometry_Outbuf(
743 ExynosVideoGeometry
*bufferConf
)
745 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
746 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
748 struct v4l2_format fmt
;
751 ALOGE("%s: Video context info must be supplied", __func__
);
752 ret
= VIDEO_ERROR_BADPARAM
;
756 if (bufferConf
== NULL
) {
757 ALOGE("%s: Buffer geometry must be supplied", __func__
);
758 ret
= VIDEO_ERROR_BADPARAM
;
762 memset(&fmt
, 0, sizeof(fmt
));
764 fmt
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
765 fmt
.fmt
.pix_mp
.pixelformat
= __ColorFormatType_To_V4L2PixelFormat(bufferConf
->eColorFormat
);
767 if (exynos_v4l2_s_fmt(pCtx
->hDec
, &fmt
) != 0) {
768 ret
= VIDEO_ERROR_APIFAIL
;
772 memcpy(&pCtx
->outbufGeometry
, bufferConf
, sizeof(pCtx
->outbufGeometry
));
779 * [Decoder Buffer OPS] Get Geometry (Output)
781 static ExynosVideoErrorType
MFC_Decoder_Get_Geometry_Outbuf(
783 ExynosVideoGeometry
*bufferConf
)
785 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
786 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
788 struct v4l2_format fmt
;
789 struct v4l2_crop crop
;
792 ALOGE("%s: Video context info must be supplied", __func__
);
793 ret
= VIDEO_ERROR_BADPARAM
;
797 if (bufferConf
== NULL
) {
798 ALOGE("%s: Buffer geometry must be supplied", __func__
);
799 ret
= VIDEO_ERROR_BADPARAM
;
803 memset(&fmt
, 0, sizeof(fmt
));
804 memset(&crop
, 0, sizeof(crop
));
806 fmt
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
807 if (exynos_v4l2_g_fmt(pCtx
->hDec
, &fmt
) != 0) {
808 ret
= VIDEO_ERROR_APIFAIL
;
812 crop
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
813 if (exynos_v4l2_g_crop(pCtx
->hDec
, &crop
) != 0) {
814 ret
= VIDEO_ERROR_APIFAIL
;
818 bufferConf
->nFrameWidth
= fmt
.fmt
.pix_mp
.width
;
819 bufferConf
->nFrameHeight
= fmt
.fmt
.pix_mp
.height
;
821 bufferConf
->cropRect
.nTop
= crop
.c
.top
;
822 bufferConf
->cropRect
.nLeft
= crop
.c
.left
;
823 bufferConf
->cropRect
.nWidth
= crop
.c
.width
;
824 bufferConf
->cropRect
.nHeight
= crop
.c
.height
;
831 * [Decoder Buffer OPS] Setup (Input)
833 static ExynosVideoErrorType
MFC_Decoder_Setup_Inbuf(
835 unsigned int nBufferCount
)
837 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
838 ExynosVideoPlane
*pVideoPlane
= NULL
;
839 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
841 struct v4l2_requestbuffers req
;
842 struct v4l2_buffer buf
;
843 struct v4l2_plane planes
[VIDEO_DECODER_INBUF_PLANES
];
847 ALOGE("%s: Video context info must be supplied", __func__
);
848 ret
= VIDEO_ERROR_BADPARAM
;
852 if (nBufferCount
== 0) {
853 ALOGE("%s: Buffer count must be greater than 0", __func__
);
854 ret
= VIDEO_ERROR_BADPARAM
;
858 ALOGV("%s: setting up inbufs (%d) shared=%s\n", __func__
, nBufferCount
,
859 pCtx
->bShareInbuf
? "true" : "false");
861 memset(&req
, 0, sizeof(req
));
863 req
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
864 req
.count
= nBufferCount
;
866 if (pCtx
->bShareInbuf
== VIDEO_TRUE
)
867 req
.memory
= pCtx
->nMemoryType
;
869 req
.memory
= V4L2_MEMORY_MMAP
;
871 if (exynos_v4l2_reqbufs(pCtx
->hDec
, &req
) != 0) {
872 ret
= VIDEO_ERROR_APIFAIL
;
876 if (req
.count
!= nBufferCount
) {
877 ALOGE("%s: asked for %d, got %d\n", __func__
, nBufferCount
, req
.count
);
878 ret
= VIDEO_ERROR_NOMEM
;
882 pCtx
->nInbufs
= (int)req
.count
;
884 pCtx
->pInbuf
= malloc(sizeof(*pCtx
->pInbuf
) * pCtx
->nInbufs
);
885 if (pCtx
->pInbuf
== NULL
) {
886 ALOGE("Failed to allocate input buffer context");
887 ret
= VIDEO_ERROR_NOMEM
;
890 memset(pCtx
->pInbuf
, 0, sizeof(*pCtx
->pInbuf
) * pCtx
->nInbufs
);
892 memset(&buf
, 0, sizeof(buf
));
894 if (pCtx
->bShareInbuf
== VIDEO_FALSE
) {
895 buf
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
896 buf
.memory
= V4L2_MEMORY_MMAP
;
897 buf
.m
.planes
= planes
;
898 buf
.length
= VIDEO_DECODER_INBUF_PLANES
;
900 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
902 if (exynos_v4l2_querybuf(pCtx
->hDec
, &buf
) != 0) {
903 ret
= VIDEO_ERROR_APIFAIL
;
907 pVideoPlane
= &pCtx
->pInbuf
[i
].planes
[0];
909 pVideoPlane
->addr
= mmap(NULL
,
910 buf
.m
.planes
[0].length
, PROT_READ
| PROT_WRITE
,
911 MAP_SHARED
, pCtx
->hDec
, buf
.m
.planes
[0].m
.mem_offset
);
913 if (pVideoPlane
->addr
== MAP_FAILED
) {
914 ret
= VIDEO_ERROR_MAPFAIL
;
918 pVideoPlane
->allocSize
= buf
.m
.planes
[0].length
;
919 pVideoPlane
->dataSize
= 0;
921 pCtx
->pInbuf
[i
].pGeometry
= &pCtx
->inbufGeometry
;
922 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
923 pCtx
->pInbuf
[i
].bRegistered
= VIDEO_TRUE
;
930 if ((pCtx
!= NULL
) && (pCtx
->pInbuf
!= NULL
)) {
931 if (pCtx
->bShareInbuf
== VIDEO_FALSE
) {
932 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
933 pVideoPlane
= &pCtx
->pInbuf
[i
].planes
[0];
934 if (pVideoPlane
->addr
== MAP_FAILED
) {
935 pVideoPlane
->addr
= NULL
;
939 munmap(pVideoPlane
->addr
, pVideoPlane
->allocSize
);
950 * [Decoder Buffer OPS] Setup (Output)
952 static ExynosVideoErrorType
MFC_Decoder_Setup_Outbuf(
954 unsigned int nBufferCount
)
956 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
957 ExynosVideoPlane
*pVideoPlane
= NULL
;
958 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
960 struct v4l2_requestbuffers req
;
961 struct v4l2_buffer buf
;
962 struct v4l2_plane planes
[VIDEO_DECODER_OUTBUF_PLANES
];
966 ALOGE("%s: Video context info must be supplied", __func__
);
967 ret
= VIDEO_ERROR_BADPARAM
;
971 if (nBufferCount
== 0) {
972 nBufferCount
= MAX_OUTPUTBUFFER_COUNT
;
973 ALOGV("%s: Change buffer count %d", __func__
, nBufferCount
);
976 ALOGV("%s: setting up outbufs (%d) shared=%s\n", __func__
, nBufferCount
,
977 pCtx
->bShareOutbuf
? "true" : "false");
979 memset(&req
, 0, sizeof(req
));
981 req
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
982 req
.count
= nBufferCount
;
984 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
)
985 req
.memory
= pCtx
->nMemoryType
;
987 req
.memory
= V4L2_MEMORY_MMAP
;
989 if (exynos_v4l2_reqbufs(pCtx
->hDec
, &req
) != 0) {
990 ret
= VIDEO_ERROR_APIFAIL
;
994 if (req
.count
!= nBufferCount
) {
995 ALOGE("%s: asked for %d, got %d\n", __func__
, nBufferCount
, req
.count
);
996 ret
= VIDEO_ERROR_NOMEM
;
1000 pCtx
->nOutbufs
= req
.count
;
1002 pCtx
->pOutbuf
= malloc(sizeof(*pCtx
->pOutbuf
) * pCtx
->nOutbufs
);
1003 if (pCtx
->pOutbuf
== NULL
) {
1004 ALOGE("Failed to allocate output buffer context");
1005 ret
= VIDEO_ERROR_NOMEM
;
1008 memset(pCtx
->pOutbuf
, 0, sizeof(*pCtx
->pOutbuf
) * pCtx
->nOutbufs
);
1010 memset(&buf
, 0, sizeof(buf
));
1012 if (pCtx
->bShareOutbuf
== VIDEO_FALSE
) {
1013 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1014 buf
.memory
= V4L2_MEMORY_MMAP
;
1015 buf
.m
.planes
= planes
;
1016 buf
.length
= VIDEO_DECODER_OUTBUF_PLANES
;
1018 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
1020 if (exynos_v4l2_querybuf(pCtx
->hDec
, &buf
) != 0) {
1021 ret
= VIDEO_ERROR_APIFAIL
;
1025 for (j
= 0; j
< VIDEO_DECODER_OUTBUF_PLANES
; j
++) {
1026 pVideoPlane
= &pCtx
->pOutbuf
[i
].planes
[j
];
1027 pVideoPlane
->addr
= mmap(NULL
,
1028 buf
.m
.planes
[j
].length
, PROT_READ
| PROT_WRITE
,
1029 MAP_SHARED
, pCtx
->hDec
, buf
.m
.planes
[j
].m
.mem_offset
);
1031 if (pVideoPlane
->addr
== MAP_FAILED
) {
1032 ret
= VIDEO_ERROR_MAPFAIL
;
1036 pVideoPlane
->allocSize
= buf
.m
.planes
[j
].length
;
1037 pVideoPlane
->dataSize
= 0;
1040 pCtx
->pOutbuf
[i
].pGeometry
= &pCtx
->outbufGeometry
;
1041 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
1042 pCtx
->pOutbuf
[i
].bSlotUsed
= VIDEO_FALSE
;
1043 pCtx
->pOutbuf
[i
].nIndexUseCnt
= 0;
1044 pCtx
->pOutbuf
[i
].bRegistered
= VIDEO_TRUE
;
1051 if ((pCtx
!= NULL
) && (pCtx
->pOutbuf
!= NULL
)) {
1052 if (pCtx
->bShareOutbuf
== VIDEO_FALSE
) {
1053 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
1054 for (j
= 0; j
< VIDEO_DECODER_OUTBUF_PLANES
; j
++) {
1055 pVideoPlane
= &pCtx
->pOutbuf
[i
].planes
[j
];
1056 if (pVideoPlane
->addr
== MAP_FAILED
) {
1057 pVideoPlane
->addr
= NULL
;
1061 munmap(pVideoPlane
->addr
, pVideoPlane
->allocSize
);
1066 free(pCtx
->pOutbuf
);
1067 pCtx
->pOutbuf
= NULL
;
1074 * [Decoder Buffer OPS] Run (Input)
1076 static ExynosVideoErrorType
MFC_Decoder_Run_Inbuf(void *pHandle
)
1078 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1079 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1082 ALOGE("%s: Video context info must be supplied", __func__
);
1083 ret
= VIDEO_ERROR_BADPARAM
;
1087 if (pCtx
->bStreamonInbuf
== VIDEO_FALSE
) {
1088 if (exynos_v4l2_streamon(pCtx
->hDec
, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) != 0) {
1089 ALOGE("%s: Failed to streamon for input buffer", __func__
);
1090 ret
= VIDEO_ERROR_APIFAIL
;
1093 pCtx
->bStreamonInbuf
= VIDEO_TRUE
;
1101 * [Decoder Buffer OPS] Run (Output)
1103 static ExynosVideoErrorType
MFC_Decoder_Run_Outbuf(void *pHandle
)
1105 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1106 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1109 ALOGE("%s: Video context info must be supplied", __func__
);
1110 ret
= VIDEO_ERROR_BADPARAM
;
1114 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
1115 if (exynos_v4l2_streamon(pCtx
->hDec
, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) != 0) {
1116 ALOGE("%s: Failed to streamon for output buffer", __func__
);
1117 ret
= VIDEO_ERROR_APIFAIL
;
1120 pCtx
->bStreamonOutbuf
= VIDEO_TRUE
;
1128 * [Decoder Buffer OPS] Stop (Input)
1130 static ExynosVideoErrorType
MFC_Decoder_Stop_Inbuf(void *pHandle
)
1132 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1133 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1137 ALOGE("%s: Video context info must be supplied", __func__
);
1138 ret
= VIDEO_ERROR_BADPARAM
;
1142 if (pCtx
->bStreamonInbuf
== VIDEO_TRUE
) {
1143 if (exynos_v4l2_streamoff(pCtx
->hDec
, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) != 0) {
1144 ALOGE("%s: Failed to streamoff for input buffer", __func__
);
1145 ret
= VIDEO_ERROR_APIFAIL
;
1148 pCtx
->bStreamonInbuf
= VIDEO_FALSE
;
1151 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
1152 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
1160 * [Decoder Buffer OPS] Stop (Output)
1162 static ExynosVideoErrorType
MFC_Decoder_Stop_Outbuf(void *pHandle
)
1164 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1165 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1169 ALOGE("%s: Video context info must be supplied", __func__
);
1170 ret
= VIDEO_ERROR_BADPARAM
;
1174 if (pCtx
->bStreamonOutbuf
== VIDEO_TRUE
) {
1175 if (exynos_v4l2_streamoff(pCtx
->hDec
, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) != 0) {
1176 ALOGE("%s: Failed to streamoff for output buffer", __func__
);
1177 ret
= VIDEO_ERROR_APIFAIL
;
1180 pCtx
->bStreamonOutbuf
= VIDEO_FALSE
;
1183 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
1184 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
1185 pCtx
->pOutbuf
[i
].bSlotUsed
= VIDEO_FALSE
;
1186 pCtx
->pOutbuf
[i
].nIndexUseCnt
= 0;
1194 * [Decoder Buffer OPS] Wait (Input)
1196 static ExynosVideoErrorType
MFC_Decoder_Wait_Inbuf(void *pHandle
)
1198 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1199 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1201 struct pollfd poll_events
;
1205 ALOGE("%s: Video context info must be supplied", __func__
);
1206 ret
= VIDEO_ERROR_BADPARAM
;
1210 poll_events
.fd
= pCtx
->hDec
;
1211 poll_events
.events
= POLLOUT
| POLLERR
;
1212 poll_events
.revents
= 0;
1215 poll_state
= poll((struct pollfd
*)&poll_events
, 1, VIDEO_DECODER_POLL_TIMEOUT
);
1216 if (poll_state
> 0) {
1217 if (poll_events
.revents
& POLLOUT
) {
1220 ALOGE("%s: Poll return error", __func__
);
1221 ret
= VIDEO_ERROR_POLL
;
1224 } else if (poll_state
< 0) {
1225 ALOGE("%s: Poll state error", __func__
);
1226 ret
= VIDEO_ERROR_POLL
;
1229 } while (poll_state
== 0);
1235 static ExynosVideoErrorType
MFC_Decoder_Register_Inbuf(
1237 ExynosVideoPlane
*planes
,
1240 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1241 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1244 if ((pCtx
== NULL
) || (planes
== NULL
) || (nPlanes
!= VIDEO_DECODER_INBUF_PLANES
)) {
1245 ALOGE("%s: params must be supplied", __func__
);
1246 ret
= VIDEO_ERROR_BADPARAM
;
1250 for (nIndex
= 0; nIndex
< pCtx
->nInbufs
; nIndex
++) {
1251 if (pCtx
->pInbuf
[nIndex
].bRegistered
== VIDEO_FALSE
) {
1252 for (plane
= 0; plane
< nPlanes
; plane
++) {
1253 pCtx
->pInbuf
[nIndex
].planes
[plane
].addr
= planes
[plane
].addr
;
1254 pCtx
->pInbuf
[nIndex
].planes
[plane
].allocSize
= planes
[plane
].allocSize
;
1255 pCtx
->pInbuf
[nIndex
].planes
[plane
].fd
= planes
[plane
].fd
;
1256 ALOGV("%s: registered buf %d (addr=%p alloc_sz=%ld fd=%d)\n", __func__
, nIndex
,
1257 planes
[plane
].addr
, planes
[plane
].allocSize
, planes
[plane
].fd
);
1259 pCtx
->pInbuf
[nIndex
].bRegistered
= VIDEO_TRUE
;
1264 if (nIndex
== pCtx
->nInbufs
) {
1265 ALOGE("%s: can not find non-registered input buffer", __func__
);
1266 ret
= VIDEO_ERROR_NOBUFFERS
;
1273 static ExynosVideoErrorType
MFC_Decoder_Register_Outbuf(
1275 ExynosVideoPlane
*planes
,
1278 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1279 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1282 if ((pCtx
== NULL
) || (planes
== NULL
) || (nPlanes
!= VIDEO_DECODER_OUTBUF_PLANES
)) {
1283 ALOGE("%s: params must be supplied", __func__
);
1284 ret
= VIDEO_ERROR_BADPARAM
;
1288 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1289 if (pCtx
->pOutbuf
[nIndex
].bRegistered
== VIDEO_FALSE
) {
1290 for (plane
= 0; plane
< nPlanes
; plane
++) {
1291 pCtx
->pOutbuf
[nIndex
].planes
[plane
].addr
= planes
[plane
].addr
;
1292 pCtx
->pOutbuf
[nIndex
].planes
[plane
].allocSize
= planes
[plane
].allocSize
;
1293 pCtx
->pOutbuf
[nIndex
].planes
[plane
].fd
= planes
[plane
].fd
;
1295 pCtx
->pOutbuf
[nIndex
].bRegistered
= VIDEO_TRUE
;
1296 ALOGV("%s: registered buf %d 0:(addr=%p alloc_sz=%d fd=%d) 1:(addr=%p alloc_sz=%d fd=%d)\n",
1297 __func__
, nIndex
, planes
[0].addr
, planes
[0].allocSize
, planes
[0].fd
,
1298 planes
[1].addr
, planes
[1].allocSize
, planes
[1].fd
);
1303 if (nIndex
== pCtx
->nOutbufs
) {
1304 ALOGE("%s: can not find non-registered output buffer", __func__
);
1305 ret
= VIDEO_ERROR_NOBUFFERS
;
1312 static ExynosVideoErrorType
MFC_Decoder_Clear_RegisteredBuffer_Inbuf(void *pHandle
)
1314 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1315 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1319 ALOGE("%s: Video context info must be supplied", __func__
);
1320 ret
= VIDEO_ERROR_BADPARAM
;
1324 for (nIndex
= 0; nIndex
< pCtx
->nInbufs
; nIndex
++) {
1325 pCtx
->pInbuf
[nIndex
].planes
[0].addr
= NULL
;
1326 pCtx
->pInbuf
[nIndex
].bRegistered
= VIDEO_FALSE
;
1333 static ExynosVideoErrorType
MFC_Decoder_Clear_RegisteredBuffer_Outbuf(void *pHandle
)
1335 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1336 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1340 ALOGE("%s: Video context info must be supplied", __func__
);
1341 ret
= VIDEO_ERROR_BADPARAM
;
1345 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1346 pCtx
->pOutbuf
[nIndex
].planes
[0].addr
= NULL
;
1347 pCtx
->pOutbuf
[nIndex
].bRegistered
= VIDEO_FALSE
;
1355 * [Decoder Buffer OPS] Find (Input)
1357 static int MFC_Decoder_Find_Inbuf(
1359 unsigned char *pBuffer
)
1361 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1365 ALOGE("%s: Video context info must be supplied", __func__
);
1369 for (nIndex
= 0; nIndex
< pCtx
->nInbufs
; nIndex
++) {
1370 if (pCtx
->pInbuf
[nIndex
].bQueued
== VIDEO_FALSE
) {
1371 if ((pBuffer
== NULL
) ||
1372 (pCtx
->pInbuf
[nIndex
].planes
[0].addr
== pBuffer
))
1377 if (nIndex
== pCtx
->nInbufs
)
1385 * [Decoder Buffer OPS] Find (Outnput)
1387 static int MFC_Decoder_Find_Outbuf(
1389 unsigned char *pBuffer
)
1391 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1395 ALOGE("%s: Video context info must be supplied", __func__
);
1399 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1400 if (pCtx
->pOutbuf
[nIndex
].bQueued
== VIDEO_FALSE
) {
1401 if ((pBuffer
== NULL
) ||
1402 (pCtx
->pOutbuf
[nIndex
].planes
[0].addr
== pBuffer
))
1407 if (nIndex
== pCtx
->nOutbufs
)
1415 * [Decoder Buffer OPS] Enqueue (Input)
1417 static ExynosVideoErrorType
MFC_Decoder_Enqueue_Inbuf(
1419 unsigned char *pBuffer
[],
1420 unsigned int dataSize
[],
1424 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1425 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1426 pthread_mutex_t
*pMutex
= NULL
;
1428 struct v4l2_plane planes
[VIDEO_DECODER_INBUF_PLANES
];
1429 struct v4l2_buffer buf
;
1433 ALOGE("%s: Video context info must be supplied", __func__
);
1434 ret
= VIDEO_ERROR_BADPARAM
;
1438 if (VIDEO_DECODER_INBUF_PLANES
< nPlanes
) {
1439 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__
,
1440 VIDEO_DECODER_INBUF_PLANES
, nPlanes
);
1441 ret
= VIDEO_ERROR_BADPARAM
;
1445 memset(&buf
, 0, sizeof(buf
));
1447 buf
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1448 buf
.m
.planes
= planes
;
1449 buf
.length
= VIDEO_DECODER_INBUF_PLANES
;
1451 pMutex
= (pthread_mutex_t
*)pCtx
->pInMutex
;
1452 pthread_mutex_lock(pMutex
);
1453 index
= MFC_Decoder_Find_Inbuf(pCtx
, pBuffer
[0]);
1455 pthread_mutex_unlock(pMutex
);
1456 ALOGE("%s: Failed to get index", __func__
);
1457 ret
= VIDEO_ERROR_NOBUFFERS
;
1462 pCtx
->pInbuf
[buf
.index
].bQueued
= VIDEO_TRUE
;
1464 if (pCtx
->bShareInbuf
== VIDEO_TRUE
) {
1465 buf
.memory
= pCtx
->nMemoryType
;
1466 for (i
= 0; i
< nPlanes
; i
++) {
1467 /* V4L2_MEMORY_USERPTR */
1468 buf
.m
.planes
[i
].m
.userptr
= (unsigned long)pBuffer
[i
];
1469 /* V4L2_MEMORY_DMABUF */
1470 buf
.m
.planes
[i
].m
.fd
= pCtx
->pInbuf
[index
].planes
[i
].fd
;
1471 buf
.m
.planes
[i
].length
= pCtx
->pInbuf
[index
].planes
[i
].allocSize
;
1472 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1473 ALOGV("%s: shared inbuf(%d) plane(%d) addr=%p fd=%d len=%d used=%d\n", __func__
,
1475 buf
.m
.planes
[i
].m
.userptr
,
1476 buf
.m
.planes
[i
].m
.fd
,
1477 buf
.m
.planes
[i
].length
,
1478 buf
.m
.planes
[i
].bytesused
);
1481 buf
.memory
= V4L2_MEMORY_MMAP
;
1482 for (i
= 0; i
< nPlanes
; i
++)
1483 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1486 // FIXME: figure out why |pPrivate| may be NULL.
1488 (((OMX_BUFFERHEADERTYPE
*)pPrivate
)->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) {
1489 buf
.flags
|= V4L2_BUF_FLAG_LAST_FRAME
;
1490 ALOGV("%s: OMX_BUFFERFLAG_EOS => LAST_FRAME: 0x%x", __func__
,
1491 !!(buf
.flags
& V4L2_BUF_FLAG_LAST_FRAME
));
1494 pCtx
->pInbuf
[buf
.index
].pPrivate
= pPrivate
;
1496 pthread_mutex_unlock(pMutex
);
1498 if (exynos_v4l2_qbuf(pCtx
->hDec
, &buf
) != 0) {
1499 ALOGE("%s: Failed to enqueue input buffer", __func__
);
1500 pthread_mutex_lock(pMutex
);
1501 pCtx
->pInbuf
[buf
.index
].pPrivate
= NULL
;
1502 pCtx
->pInbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1503 pthread_mutex_unlock(pMutex
);
1504 ret
= VIDEO_ERROR_APIFAIL
;
1513 * [Decoder Buffer OPS] Enqueue (Output)
1515 static ExynosVideoErrorType
MFC_Decoder_Enqueue_Outbuf(
1517 unsigned char *pBuffer
[],
1518 unsigned int dataSize
[],
1522 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1523 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1524 pthread_mutex_t
*pMutex
= NULL
;
1526 struct v4l2_plane planes
[VIDEO_DECODER_OUTBUF_PLANES
];
1527 struct v4l2_buffer buf
;
1531 ALOGE("%s: Video context info must be supplied", __func__
);
1532 ret
= VIDEO_ERROR_BADPARAM
;
1536 if (VIDEO_DECODER_OUTBUF_PLANES
< nPlanes
) {
1537 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__
,
1538 VIDEO_DECODER_OUTBUF_PLANES
, nPlanes
);
1539 ret
= VIDEO_ERROR_BADPARAM
;
1543 memset(&buf
, 0, sizeof(buf
));
1544 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1545 buf
.m
.planes
= planes
;
1546 buf
.length
= VIDEO_DECODER_OUTBUF_PLANES
;
1548 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
1549 pthread_mutex_lock(pMutex
);
1550 index
= MFC_Decoder_Find_Outbuf(pCtx
, pBuffer
[0]);
1552 pthread_mutex_unlock(pMutex
);
1553 ALOGE("%s: Failed to get index", __func__
);
1554 ret
= VIDEO_ERROR_NOBUFFERS
;
1558 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_TRUE
;
1560 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
) {
1561 buf
.memory
= pCtx
->nMemoryType
;
1562 for (i
= 0; i
< nPlanes
; i
++) {
1563 /* V4L2_MEMORY_USERPTR */
1564 buf
.m
.planes
[i
].m
.userptr
= (unsigned long)pBuffer
[i
];
1565 /* V4L2_MEMORY_DMABUF */
1566 buf
.m
.planes
[i
].m
.fd
= pCtx
->pOutbuf
[index
].planes
[i
].fd
;
1567 buf
.m
.planes
[i
].length
= pCtx
->pOutbuf
[index
].planes
[i
].allocSize
;
1568 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1569 ALOGV("%s: shared outbuf(%d) plane=%d addr=%p fd=%d len=%d used=%d\n", __func__
,
1571 buf
.m
.planes
[i
].m
.userptr
,
1572 buf
.m
.planes
[i
].m
.fd
,
1573 buf
.m
.planes
[i
].length
,
1574 buf
.m
.planes
[i
].bytesused
);
1577 ALOGV("%s: non-shared outbuf(%d)\n", __func__
, index
);
1578 buf
.memory
= V4L2_MEMORY_MMAP
;
1581 pCtx
->pOutbuf
[buf
.index
].pPrivate
= pPrivate
;
1583 pthread_mutex_unlock(pMutex
);
1585 if (exynos_v4l2_qbuf(pCtx
->hDec
, &buf
) != 0) {
1586 ALOGE("%s: Failed to enqueue output buffer", __func__
);
1587 pthread_mutex_lock(pMutex
);
1588 pCtx
->pOutbuf
[buf
.index
].pPrivate
= NULL
;
1589 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1590 pthread_mutex_unlock(pMutex
);
1591 ret
= VIDEO_ERROR_APIFAIL
;
1600 * [Decoder Buffer OPS] Dequeue (Input)
1602 static ExynosVideoBuffer
*MFC_Decoder_Dequeue_Inbuf(void *pHandle
)
1604 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1605 ExynosVideoBuffer
*pInbuf
= NULL
;
1606 pthread_mutex_t
*pMutex
= NULL
;
1608 struct v4l2_buffer buf
;
1611 ALOGE("%s: Video context info must be supplied", __func__
);
1615 if (pCtx
->bStreamonInbuf
== VIDEO_FALSE
) {
1620 memset(&buf
, 0, sizeof(buf
));
1622 buf
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1624 if (pCtx
->bShareInbuf
== VIDEO_TRUE
)
1625 buf
.memory
= pCtx
->nMemoryType
;
1627 buf
.memory
= V4L2_MEMORY_MMAP
;
1629 if (exynos_v4l2_dqbuf(pCtx
->hDec
, &buf
) != 0) {
1634 pMutex
= (pthread_mutex_t
*)pCtx
->pInMutex
;
1635 pthread_mutex_lock(pMutex
);
1637 pInbuf
= &pCtx
->pInbuf
[buf
.index
];
1638 pCtx
->pInbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1640 if (pCtx
->bStreamonInbuf
== VIDEO_FALSE
)
1643 pthread_mutex_unlock(pMutex
);
1650 * [Decoder Buffer OPS] Dequeue (Output)
1652 static ExynosVideoBuffer
*MFC_Decoder_Dequeue_Outbuf(void *pHandle
)
1654 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1655 ExynosVideoBuffer
*pOutbuf
= NULL
;
1656 pthread_mutex_t
*pMutex
= NULL
;
1658 struct v4l2_buffer buf
;
1662 ALOGE("%s: Video context info must be supplied", __func__
);
1666 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
1671 memset(&buf
, 0, sizeof(buf
));
1672 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1674 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
)
1675 buf
.memory
= pCtx
->nMemoryType
;
1677 buf
.memory
= V4L2_MEMORY_MMAP
;
1679 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
1680 if (exynos_v4l2_dqbuf(pCtx
->hDec
, &buf
) != 0) {
1685 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
1690 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
1691 pthread_mutex_lock(pMutex
);
1693 pOutbuf
= &pCtx
->pOutbuf
[buf
.index
];
1695 exynos_v4l2_g_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS
, &value
);
1699 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DECODING_ONLY
;
1702 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DISPLAY_DECODING
;
1705 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DISPLAY_ONLY
;
1708 exynos_v4l2_g_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE
, &state
);
1709 if (state
== 1) /* Resolution is changed */
1710 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_CHANGE_RESOL
;
1711 else /* Decoding is finished */
1712 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DECODING_FINISHED
;
1715 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_UNKNOWN
;
1719 switch (buf
.flags
& (0x7 << 3)) {
1720 case V4L2_BUF_FLAG_KEYFRAME
:
1721 pOutbuf
->frameType
= VIDEO_FRAME_I
;
1723 case V4L2_BUF_FLAG_PFRAME
:
1724 pOutbuf
->frameType
= VIDEO_FRAME_P
;
1726 case V4L2_BUF_FLAG_BFRAME
:
1727 pOutbuf
->frameType
= VIDEO_FRAME_B
;
1730 pOutbuf
->frameType
= VIDEO_FRAME_OTHERS
;
1734 pOutbuf
->bQueued
= VIDEO_FALSE
;
1736 pthread_mutex_unlock(pMutex
);
1742 static ExynosVideoErrorType
MFC_Decoder_Clear_Queued_Inbuf(void *pHandle
)
1744 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1745 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1749 ALOGE("%s: Video context info must be supplied", __func__
);
1750 ret
= VIDEO_ERROR_BADPARAM
;
1754 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
1755 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
1762 static ExynosVideoErrorType
MFC_Decoder_Clear_Queued_Outbuf(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
->nOutbufs
; i
++) {
1775 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
1783 * [Decoder Buffer OPS] Cleanup Buffer (Input)
1785 static ExynosVideoErrorType
MFC_Decoder_Cleanup_Buffer_Inbuf(void *pHandle
)
1787 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1788 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1790 struct v4l2_requestbuffers req
;
1791 int nBufferCount
= 0;
1794 ALOGE("%s: Video context info must be supplied", __func__
);
1795 ret
= VIDEO_ERROR_BADPARAM
;
1799 nBufferCount
= 0; /* for clean-up */
1801 memset(&req
, 0, sizeof(req
));
1803 req
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1804 req
.count
= nBufferCount
;
1806 if (pCtx
->bShareInbuf
== VIDEO_TRUE
)
1807 req
.memory
= pCtx
->nMemoryType
;
1809 req
.memory
= V4L2_MEMORY_MMAP
;
1811 if (exynos_v4l2_reqbufs(pCtx
->hDec
, &req
) != 0) {
1812 ret
= VIDEO_ERROR_APIFAIL
;
1816 pCtx
->nInbufs
= (int)req
.count
;
1818 if (pCtx
->pInbuf
!= NULL
) {
1820 pCtx
->pInbuf
= NULL
;
1828 * [Decoder Buffer OPS] Cleanup Buffer (Output)
1830 static ExynosVideoErrorType
MFC_Decoder_Cleanup_Buffer_Outbuf(void *pHandle
)
1832 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1833 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1835 struct v4l2_requestbuffers req
;
1836 int nBufferCount
= 0;
1839 ALOGE("%s: Video context info must be supplied", __func__
);
1840 ret
= VIDEO_ERROR_BADPARAM
;
1844 nBufferCount
= 0; /* for clean-up */
1846 memset(&req
, 0, sizeof(req
));
1848 req
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1849 req
.count
= nBufferCount
;
1851 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
)
1852 req
.memory
= pCtx
->nMemoryType
;
1854 req
.memory
= V4L2_MEMORY_MMAP
;
1856 if (exynos_v4l2_reqbufs(pCtx
->hDec
, &req
) != 0) {
1857 ret
= VIDEO_ERROR_APIFAIL
;
1861 pCtx
->nOutbufs
= (int)req
.count
;
1863 if (pCtx
->pOutbuf
!= NULL
) {
1864 free(pCtx
->pOutbuf
);
1865 pCtx
->pOutbuf
= NULL
;
1873 * [Decoder Buffer OPS] FindIndex (Output)
1875 static int MFC_Decoder_FindEmpty_Outbuf(void *pHandle
)
1877 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1881 ALOGE("%s: Video context info must be supplied", __func__
);
1885 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1886 if ((pCtx
->pOutbuf
[nIndex
].bQueued
== VIDEO_FALSE
) &&
1887 (pCtx
->pOutbuf
[nIndex
].bSlotUsed
== VIDEO_FALSE
))
1891 if (nIndex
== pCtx
->nOutbufs
)
1899 * [Decoder Buffer OPS] BufferIndexFree (Output)
1901 void MFC_Decoder_BufferIndexFree_Outbuf(void *pHandle
, PrivateDataShareBuffer
*pPDSB
, int index
)
1903 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1906 ALOGV("De-queue buf.index:%d", index
);
1907 ALOGV("pOutbuf fd:%d", pCtx
->pOutbuf
[index
].planes
[0].fd
);
1909 if (pCtx
->pOutbuf
[index
].nIndexUseCnt
== 0) {
1910 pCtx
->pOutbuf
[index
].bSlotUsed
= VIDEO_FALSE
;
1913 for (i
= 0; pPDSB
->dpbFD
[i
].fd
> -1; i
++) {
1914 ALOGV("pPDSB->dpbFD[%d].fd:%d", i
, pPDSB
->dpbFD
[i
].fd
);
1915 for (j
= 0; pCtx
->nOutbufs
> j
; j
++)
1916 if (pPDSB
->dpbFD
[i
].fd
== pCtx
->pOutbuf
[j
].planes
[0].fd
) {
1917 if (pCtx
->pOutbuf
[j
].bQueued
== VIDEO_FALSE
) {
1918 if (pCtx
->pOutbuf
[j
].nIndexUseCnt
> 0)
1919 pCtx
->pOutbuf
[j
].nIndexUseCnt
--;
1920 } else if(pCtx
->pOutbuf
[j
].bQueued
== VIDEO_TRUE
) {
1921 if (pCtx
->pOutbuf
[j
].nIndexUseCnt
> 1) {
1922 /* The buffer being used as the reference buffer came again. */
1923 pCtx
->pOutbuf
[j
].nIndexUseCnt
--;
1925 /* Reference DPB buffer is internally reused. */
1928 ALOGV("dec FD:%d, pCtx->pOutbuf[%d].nIndexUseCnt:%d", pPDSB
->dpbFD
[i
].fd
, j
, pCtx
->pOutbuf
[j
].nIndexUseCnt
);
1929 if ((pCtx
->pOutbuf
[j
].nIndexUseCnt
== 0) &&
1930 (pCtx
->pOutbuf
[j
].bQueued
== VIDEO_FALSE
)) {
1931 pCtx
->pOutbuf
[j
].bSlotUsed
= VIDEO_FALSE
;
1935 memset((char *)pPDSB
, -1, sizeof(PrivateDataShareBuffer
));
1941 * [Decoder Buffer OPS] ExtensionEnqueue (Output)
1943 static ExynosVideoErrorType
MFC_Decoder_ExtensionEnqueue_Outbuf(
1945 unsigned char *pBuffer
[],
1946 unsigned int *pFd
[],
1947 unsigned int allocLen
[],
1948 unsigned int dataSize
[],
1952 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1953 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1954 pthread_mutex_t
*pMutex
= NULL
;
1956 struct v4l2_plane planes
[VIDEO_DECODER_OUTBUF_PLANES
];
1957 struct v4l2_buffer buf
;
1958 int state
, index
, i
;
1961 ALOGE("%s: Video context info must be supplied", __func__
);
1962 ret
= VIDEO_ERROR_BADPARAM
;
1966 if (VIDEO_DECODER_OUTBUF_PLANES
< nPlanes
) {
1967 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__
,
1968 VIDEO_DECODER_OUTBUF_PLANES
, nPlanes
);
1969 ret
= VIDEO_ERROR_BADPARAM
;
1973 memset(&buf
, 0, sizeof(buf
));
1974 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1975 buf
.m
.planes
= planes
;
1976 buf
.length
= VIDEO_DECODER_OUTBUF_PLANES
;
1978 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
1979 pthread_mutex_lock(pMutex
);
1981 index
= MFC_Decoder_Find_Outbuf(pCtx
, pBuffer
[0]);
1983 ALOGV("%s: Failed to find index", __func__
);
1984 index
= MFC_Decoder_FindEmpty_Outbuf(pCtx
);
1986 pthread_mutex_unlock(pMutex
);
1987 ALOGE("%s: Failed to get index", __func__
);
1988 ret
= VIDEO_ERROR_NOBUFFERS
;
1994 ALOGV("En-queue index:%d pCtx->pOutbuf[buf.index].bQueued:%d, pFd[0]:%d",
1995 index
, pCtx
->pOutbuf
[buf
.index
].bQueued
, pFd
[0]);
1996 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_TRUE
;
1997 pCtx
->pOutbuf
[buf
.index
].bSlotUsed
= VIDEO_TRUE
;
1999 buf
.memory
= pCtx
->nMemoryType
;
2000 for (i
= 0; i
< nPlanes
; i
++) {
2001 /* V4L2_MEMORY_USERPTR */
2002 buf
.m
.planes
[i
].m
.userptr
= (unsigned long)pBuffer
[i
];
2003 /* V4L2_MEMORY_DMABUF */
2004 buf
.m
.planes
[i
].m
.fd
= pFd
[i
];
2005 buf
.m
.planes
[i
].length
= allocLen
[i
];
2006 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
2008 /* Temporary storage for Dequeue */
2009 pCtx
->pOutbuf
[buf
.index
].planes
[i
].addr
= (unsigned long)pBuffer
[i
];
2010 pCtx
->pOutbuf
[buf
.index
].planes
[i
].fd
= (unsigned int)pFd
[i
];
2011 pCtx
->pOutbuf
[buf
.index
].planes
[i
].allocSize
= allocLen
[i
];
2013 ALOGV("%s: shared outbuf(%d) plane=%d addr=0x%x fd=%d len=%d used=%d\n",
2015 (void*)buf
.m
.planes
[i
].m
.userptr
, buf
.m
.planes
[i
].m
.fd
,
2016 buf
.m
.planes
[i
].length
, buf
.m
.planes
[i
].bytesused
);
2019 pCtx
->pOutbuf
[buf
.index
].pPrivate
= pPrivate
;
2020 pCtx
->pOutbuf
[buf
.index
].nIndexUseCnt
++;
2022 pthread_mutex_unlock(pMutex
);
2024 if (exynos_v4l2_qbuf(pCtx
->hDec
, &buf
) != 0) {
2025 pthread_mutex_lock(pMutex
);
2026 pCtx
->pOutbuf
[buf
.index
].nIndexUseCnt
--;
2027 pCtx
->pOutbuf
[buf
.index
].pPrivate
= NULL
;
2028 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
2029 if (pCtx
->pOutbuf
[buf
.index
].nIndexUseCnt
== 0)
2030 pCtx
->pOutbuf
[buf
.index
].bSlotUsed
= VIDEO_FALSE
;
2031 exynos_v4l2_g_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE
, &state
);
2032 pthread_mutex_unlock(pMutex
);
2035 /* The case of Resolution is changed */
2036 ret
= VIDEO_ERROR_WRONGBUFFERSIZE
;
2038 ALOGE("%s: Failed to enqueue output buffer", __func__
);
2039 ret
= VIDEO_ERROR_APIFAIL
;
2049 * [Decoder Buffer OPS] ExtensionDequeue (Output)
2051 static ExynosVideoErrorType
MFC_Decoder_ExtensionDequeue_Outbuf(
2053 ExynosVideoBuffer
*pVideoBuffer
)
2055 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
2056 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
2057 pthread_mutex_t
*pMutex
= NULL
;
2058 ExynosVideoBuffer
*pOutbuf
= NULL
;
2059 PrivateDataShareBuffer
*pPDSB
= NULL
;
2060 struct v4l2_buffer buf
;
2061 int value
, state
, i
, j
;
2064 ALOGE("%s: Video context info must be supplied", __func__
);
2065 ret
= VIDEO_ERROR_BADPARAM
;
2069 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
2071 ret
= VIDEO_ERROR_APIFAIL
;
2075 memset(&buf
, 0, sizeof(buf
));
2076 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
2078 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
)
2079 buf
.memory
= pCtx
->nMemoryType
;
2081 buf
.memory
= V4L2_MEMORY_MMAP
;
2083 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
2084 if (exynos_v4l2_dqbuf(pCtx
->hDec
, &buf
) != 0) {
2086 ret
= VIDEO_ERROR_APIFAIL
;
2090 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
2091 pthread_mutex_lock(pMutex
);
2093 pOutbuf
= &pCtx
->pOutbuf
[buf
.index
];
2094 exynos_v4l2_g_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS
, &value
);
2098 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DECODING_ONLY
;
2101 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DISPLAY_DECODING
;
2104 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DISPLAY_ONLY
;
2107 exynos_v4l2_g_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE
, &state
);
2108 if (state
== 1) /* Resolution is changed */
2109 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_CHANGE_RESOL
;
2110 else /* Decoding is finished */
2111 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DECODING_FINISHED
;
2114 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_UNKNOWN
;
2118 switch (buf
.flags
& (0x7 << 3)) {
2119 case V4L2_BUF_FLAG_KEYFRAME
:
2120 pOutbuf
->frameType
= VIDEO_FRAME_I
;
2122 case V4L2_BUF_FLAG_PFRAME
:
2123 pOutbuf
->frameType
= VIDEO_FRAME_P
;
2125 case V4L2_BUF_FLAG_BFRAME
:
2126 pOutbuf
->frameType
= VIDEO_FRAME_B
;
2129 pOutbuf
->frameType
= VIDEO_FRAME_OTHERS
;
2133 pPDSB
= ((PrivateDataShareBuffer
*)pCtx
->nPrivateDataShareAddress
) + buf
.index
;
2134 if (pCtx
->pOutbuf
[buf
.index
].bQueued
== VIDEO_TRUE
) {
2135 memcpy(pVideoBuffer
, pOutbuf
, sizeof(ExynosVideoBuffer
));
2136 memcpy((char *)(&(pVideoBuffer
->PDSB
)), (char *)pPDSB
, sizeof(PrivateDataShareBuffer
));
2138 ret
= VIDEO_ERROR_NOBUFFERS
;
2139 ALOGV("%s :: %d", __FUNCTION__
, __LINE__
);
2142 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
2143 MFC_Decoder_BufferIndexFree_Outbuf(pHandle
, pPDSB
, buf
.index
);
2145 pthread_mutex_unlock(pMutex
);
2152 * [Decoder Buffer OPS] Enable Dynamic DPB
2154 static ExynosVideoErrorType
MFC_Decoder_Enable_DynamicDPB(void *pHandle
)
2156 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
2157 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
2160 ALOGE("%s: Video context info must be supplied", __func__
);
2161 ret
= VIDEO_ERROR_BADPARAM
;
2165 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE
, 1) != 0) {
2166 ret
= VIDEO_ERROR_APIFAIL
;
2170 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC_SET_USER_SHARED_HANDLE
, pCtx
->nPrivateDataShareFD
) != 0) {
2171 ret
= VIDEO_ERROR_APIFAIL
;
2180 * [Decoder OPS] Common
2182 static ExynosVideoDecOps defDecOps
= {
2184 .Init
= MFC_Decoder_Init
,
2185 .Finalize
= MFC_Decoder_Finalize
,
2186 .Set_DisplayDelay
= MFC_Decoder_Set_DisplayDelay
,
2187 .Set_IFrameDecoding
= MFC_Decoder_Set_IFrameDecoding
,
2188 .Enable_PackedPB
= MFC_Decoder_Enable_PackedPB
,
2189 .Enable_LoopFilter
= MFC_Decoder_Enable_LoopFilter
,
2190 .Enable_SliceMode
= MFC_Decoder_Enable_SliceMode
,
2191 .Get_ActualBufferCount
= MFC_Decoder_Get_ActualBufferCount
,
2192 .Set_FrameTag
= MFC_Decoder_Set_FrameTag
,
2193 .Get_FrameTag
= MFC_Decoder_Get_FrameTag
,
2194 .Enable_SEIParsing
= MFC_Decoder_Enable_SEIParsing
,
2195 .Get_FramePackingInfo
= MFC_Decoder_Get_FramePackingInfo
,
2199 * [Decoder Buffer OPS] Input
2201 static ExynosVideoDecBufferOps defInbufOps
= {
2203 .Enable_Cacheable
= MFC_Decoder_Enable_Cacheable_Inbuf
,
2204 .Set_Shareable
= MFC_Decoder_Set_Shareable_Inbuf
,
2206 .Set_Geometry
= MFC_Decoder_Set_Geometry_Inbuf
,
2207 .Get_Geometry
= NULL
,
2208 .Setup
= MFC_Decoder_Setup_Inbuf
,
2209 .Run
= MFC_Decoder_Run_Inbuf
,
2210 .Stop
= MFC_Decoder_Stop_Inbuf
,
2211 .Enqueue
= MFC_Decoder_Enqueue_Inbuf
,
2212 .Enqueue_All
= NULL
,
2213 .Dequeue
= MFC_Decoder_Dequeue_Inbuf
,
2214 .Register
= MFC_Decoder_Register_Inbuf
,
2215 .Clear_RegisteredBuffer
= MFC_Decoder_Clear_RegisteredBuffer_Inbuf
,
2216 .Clear_Queue
= MFC_Decoder_Clear_Queued_Inbuf
,
2217 .Cleanup_Buffer
= MFC_Decoder_Cleanup_Buffer_Inbuf
,
2221 * [Decoder Buffer OPS] Output
2223 static ExynosVideoDecBufferOps defOutbufOps
= {
2225 .Enable_Cacheable
= MFC_Decoder_Enable_Cacheable_Outbuf
,
2226 .Set_Shareable
= MFC_Decoder_Set_Shareable_Outbuf
,
2227 .Get_Buffer
= MFC_Decoder_Get_Buffer_Outbuf
,
2228 .Set_Geometry
= MFC_Decoder_Set_Geometry_Outbuf
,
2229 .Get_Geometry
= MFC_Decoder_Get_Geometry_Outbuf
,
2230 .Setup
= MFC_Decoder_Setup_Outbuf
,
2231 .Run
= MFC_Decoder_Run_Outbuf
,
2232 .Stop
= MFC_Decoder_Stop_Outbuf
,
2233 .Enqueue
= MFC_Decoder_Enqueue_Outbuf
,
2234 .Enqueue_All
= NULL
,
2235 .Dequeue
= MFC_Decoder_Dequeue_Outbuf
,
2236 .Register
= MFC_Decoder_Register_Outbuf
,
2237 .Clear_RegisteredBuffer
= MFC_Decoder_Clear_RegisteredBuffer_Outbuf
,
2238 .Clear_Queue
= MFC_Decoder_Clear_Queued_Outbuf
,
2239 .Cleanup_Buffer
= MFC_Decoder_Cleanup_Buffer_Outbuf
,
2240 .ExtensionEnqueue
= MFC_Decoder_ExtensionEnqueue_Outbuf
,
2241 .ExtensionDequeue
= MFC_Decoder_ExtensionDequeue_Outbuf
,
2242 .Enable_DynamicDPB
= MFC_Decoder_Enable_DynamicDPB
,
2245 int Exynos_Video_Register_Decoder(
2246 ExynosVideoDecOps
*pDecOps
,
2247 ExynosVideoDecBufferOps
*pInbufOps
,
2248 ExynosVideoDecBufferOps
*pOutbufOps
)
2250 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
2252 if ((pDecOps
== NULL
) || (pInbufOps
== NULL
) || (pOutbufOps
== NULL
)) {
2253 ret
= VIDEO_ERROR_BADPARAM
;
2257 defDecOps
.nSize
= sizeof(defDecOps
);
2258 defInbufOps
.nSize
= sizeof(defInbufOps
);
2259 defOutbufOps
.nSize
= sizeof(defOutbufOps
);
2261 memcpy((char *)pDecOps
+ sizeof(pDecOps
->nSize
), (char *)&defDecOps
+ sizeof(defDecOps
.nSize
),
2262 pDecOps
->nSize
- sizeof(pDecOps
->nSize
));
2264 memcpy((char *)pInbufOps
+ sizeof(pInbufOps
->nSize
), (char *)&defInbufOps
+ sizeof(defInbufOps
.nSize
),
2265 pInbufOps
->nSize
- sizeof(pInbufOps
->nSize
));
2267 memcpy((char *)pOutbufOps
+ sizeof(pOutbufOps
->nSize
), (char *)&defOutbufOps
+ sizeof(defOutbufOps
.nSize
),
2268 pOutbufOps
->nSize
- sizeof(pOutbufOps
->nSize
));