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
);
1073 * [Decoder Buffer OPS] Run (Input)
1075 static ExynosVideoErrorType
MFC_Decoder_Run_Inbuf(void *pHandle
)
1077 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1078 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1081 ALOGE("%s: Video context info must be supplied", __func__
);
1082 ret
= VIDEO_ERROR_BADPARAM
;
1086 if (pCtx
->bStreamonInbuf
== VIDEO_FALSE
) {
1087 if (exynos_v4l2_streamon(pCtx
->hDec
, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) != 0) {
1088 ALOGE("%s: Failed to streamon for input buffer", __func__
);
1089 ret
= VIDEO_ERROR_APIFAIL
;
1092 pCtx
->bStreamonInbuf
= VIDEO_TRUE
;
1100 * [Decoder Buffer OPS] Run (Output)
1102 static ExynosVideoErrorType
MFC_Decoder_Run_Outbuf(void *pHandle
)
1104 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1105 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1108 ALOGE("%s: Video context info must be supplied", __func__
);
1109 ret
= VIDEO_ERROR_BADPARAM
;
1113 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
1114 if (exynos_v4l2_streamon(pCtx
->hDec
, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) != 0) {
1115 ALOGE("%s: Failed to streamon for output buffer", __func__
);
1116 ret
= VIDEO_ERROR_APIFAIL
;
1119 pCtx
->bStreamonOutbuf
= VIDEO_TRUE
;
1127 * [Decoder Buffer OPS] Stop (Input)
1129 static ExynosVideoErrorType
MFC_Decoder_Stop_Inbuf(void *pHandle
)
1131 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1132 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1136 ALOGE("%s: Video context info must be supplied", __func__
);
1137 ret
= VIDEO_ERROR_BADPARAM
;
1141 if (pCtx
->bStreamonInbuf
== VIDEO_TRUE
) {
1142 if (exynos_v4l2_streamoff(pCtx
->hDec
, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) != 0) {
1143 ALOGE("%s: Failed to streamoff for input buffer", __func__
);
1144 ret
= VIDEO_ERROR_APIFAIL
;
1147 pCtx
->bStreamonInbuf
= VIDEO_FALSE
;
1150 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
1151 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
1159 * [Decoder Buffer OPS] Stop (Output)
1161 static ExynosVideoErrorType
MFC_Decoder_Stop_Outbuf(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
->bStreamonOutbuf
== VIDEO_TRUE
) {
1174 if (exynos_v4l2_streamoff(pCtx
->hDec
, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) != 0) {
1175 ALOGE("%s: Failed to streamoff for output buffer", __func__
);
1176 ret
= VIDEO_ERROR_APIFAIL
;
1179 pCtx
->bStreamonOutbuf
= VIDEO_FALSE
;
1182 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
1183 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
1184 pCtx
->pOutbuf
[i
].bSlotUsed
= VIDEO_FALSE
;
1185 pCtx
->pOutbuf
[i
].nIndexUseCnt
= 0;
1193 * [Decoder Buffer OPS] Wait (Input)
1195 static ExynosVideoErrorType
MFC_Decoder_Wait_Inbuf(void *pHandle
)
1197 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1198 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1200 struct pollfd poll_events
;
1204 ALOGE("%s: Video context info must be supplied", __func__
);
1205 ret
= VIDEO_ERROR_BADPARAM
;
1209 poll_events
.fd
= pCtx
->hDec
;
1210 poll_events
.events
= POLLOUT
| POLLERR
;
1211 poll_events
.revents
= 0;
1214 poll_state
= poll((struct pollfd
*)&poll_events
, 1, VIDEO_DECODER_POLL_TIMEOUT
);
1215 if (poll_state
> 0) {
1216 if (poll_events
.revents
& POLLOUT
) {
1219 ALOGE("%s: Poll return error", __func__
);
1220 ret
= VIDEO_ERROR_POLL
;
1223 } else if (poll_state
< 0) {
1224 ALOGE("%s: Poll state error", __func__
);
1225 ret
= VIDEO_ERROR_POLL
;
1228 } while (poll_state
== 0);
1234 static ExynosVideoErrorType
MFC_Decoder_Register_Inbuf(
1236 ExynosVideoPlane
*planes
,
1239 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1240 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1243 if ((pCtx
== NULL
) || (planes
== NULL
) || (nPlanes
!= VIDEO_DECODER_INBUF_PLANES
)) {
1244 ALOGE("%s: params must be supplied", __func__
);
1245 ret
= VIDEO_ERROR_BADPARAM
;
1249 for (nIndex
= 0; nIndex
< pCtx
->nInbufs
; nIndex
++) {
1250 if (pCtx
->pInbuf
[nIndex
].bRegistered
== VIDEO_FALSE
) {
1251 for (plane
= 0; plane
< nPlanes
; plane
++) {
1252 pCtx
->pInbuf
[nIndex
].planes
[plane
].addr
= planes
[plane
].addr
;
1253 pCtx
->pInbuf
[nIndex
].planes
[plane
].allocSize
= planes
[plane
].allocSize
;
1254 pCtx
->pInbuf
[nIndex
].planes
[plane
].fd
= planes
[plane
].fd
;
1255 ALOGV("%s: registered buf %d (addr=%p alloc_sz=%ld fd=%d)\n", __func__
, nIndex
,
1256 planes
[plane
].addr
, planes
[plane
].allocSize
, planes
[plane
].fd
);
1258 pCtx
->pInbuf
[nIndex
].bRegistered
= VIDEO_TRUE
;
1263 if (nIndex
== pCtx
->nInbufs
) {
1264 ALOGE("%s: can not find non-registered input buffer", __func__
);
1265 ret
= VIDEO_ERROR_NOBUFFERS
;
1272 static ExynosVideoErrorType
MFC_Decoder_Register_Outbuf(
1274 ExynosVideoPlane
*planes
,
1277 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1278 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1281 if ((pCtx
== NULL
) || (planes
== NULL
) || (nPlanes
!= VIDEO_DECODER_OUTBUF_PLANES
)) {
1282 ALOGE("%s: params must be supplied", __func__
);
1283 ret
= VIDEO_ERROR_BADPARAM
;
1287 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1288 if (pCtx
->pOutbuf
[nIndex
].bRegistered
== VIDEO_FALSE
) {
1289 for (plane
= 0; plane
< nPlanes
; plane
++) {
1290 pCtx
->pOutbuf
[nIndex
].planes
[plane
].addr
= planes
[plane
].addr
;
1291 pCtx
->pOutbuf
[nIndex
].planes
[plane
].allocSize
= planes
[plane
].allocSize
;
1292 pCtx
->pOutbuf
[nIndex
].planes
[plane
].fd
= planes
[plane
].fd
;
1294 pCtx
->pOutbuf
[nIndex
].bRegistered
= VIDEO_TRUE
;
1295 ALOGV("%s: registered buf %d 0:(addr=%p alloc_sz=%d fd=%d) 1:(addr=%p alloc_sz=%d fd=%d)\n",
1296 __func__
, nIndex
, planes
[0].addr
, planes
[0].allocSize
, planes
[0].fd
,
1297 planes
[1].addr
, planes
[1].allocSize
, planes
[1].fd
);
1302 if (nIndex
== pCtx
->nOutbufs
) {
1303 ALOGE("%s: can not find non-registered output buffer", __func__
);
1304 ret
= VIDEO_ERROR_NOBUFFERS
;
1311 static ExynosVideoErrorType
MFC_Decoder_Clear_RegisteredBuffer_Inbuf(void *pHandle
)
1313 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1314 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1318 ALOGE("%s: Video context info must be supplied", __func__
);
1319 ret
= VIDEO_ERROR_BADPARAM
;
1323 for (nIndex
= 0; nIndex
< pCtx
->nInbufs
; nIndex
++) {
1324 pCtx
->pInbuf
[nIndex
].planes
[0].addr
= NULL
;
1325 pCtx
->pInbuf
[nIndex
].bRegistered
= VIDEO_FALSE
;
1332 static ExynosVideoErrorType
MFC_Decoder_Clear_RegisteredBuffer_Outbuf(void *pHandle
)
1334 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1335 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1339 ALOGE("%s: Video context info must be supplied", __func__
);
1340 ret
= VIDEO_ERROR_BADPARAM
;
1344 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1345 pCtx
->pOutbuf
[nIndex
].planes
[0].addr
= NULL
;
1346 pCtx
->pOutbuf
[nIndex
].bRegistered
= VIDEO_FALSE
;
1354 * [Decoder Buffer OPS] Find (Input)
1356 static int MFC_Decoder_Find_Inbuf(
1358 unsigned char *pBuffer
)
1360 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1364 ALOGE("%s: Video context info must be supplied", __func__
);
1368 for (nIndex
= 0; nIndex
< pCtx
->nInbufs
; nIndex
++) {
1369 if (pCtx
->pInbuf
[nIndex
].bQueued
== VIDEO_FALSE
) {
1370 if ((pBuffer
== NULL
) ||
1371 (pCtx
->pInbuf
[nIndex
].planes
[0].addr
== pBuffer
))
1376 if (nIndex
== pCtx
->nInbufs
)
1384 * [Decoder Buffer OPS] Find (Outnput)
1386 static int MFC_Decoder_Find_Outbuf(
1388 unsigned char *pBuffer
)
1390 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1394 ALOGE("%s: Video context info must be supplied", __func__
);
1398 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1399 if (pCtx
->pOutbuf
[nIndex
].bQueued
== VIDEO_FALSE
) {
1400 if ((pBuffer
== NULL
) ||
1401 (pCtx
->pOutbuf
[nIndex
].planes
[0].addr
== pBuffer
))
1406 if (nIndex
== pCtx
->nOutbufs
)
1414 * [Decoder Buffer OPS] Enqueue (Input)
1416 static ExynosVideoErrorType
MFC_Decoder_Enqueue_Inbuf(
1418 unsigned char *pBuffer
[],
1419 unsigned int dataSize
[],
1423 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1424 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1425 pthread_mutex_t
*pMutex
= NULL
;
1427 struct v4l2_plane planes
[VIDEO_DECODER_INBUF_PLANES
];
1428 struct v4l2_buffer buf
;
1432 ALOGE("%s: Video context info must be supplied", __func__
);
1433 ret
= VIDEO_ERROR_BADPARAM
;
1437 if (VIDEO_DECODER_INBUF_PLANES
< nPlanes
) {
1438 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__
,
1439 VIDEO_DECODER_INBUF_PLANES
, nPlanes
);
1440 ret
= VIDEO_ERROR_BADPARAM
;
1444 memset(&buf
, 0, sizeof(buf
));
1446 buf
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1447 buf
.m
.planes
= planes
;
1448 buf
.length
= VIDEO_DECODER_INBUF_PLANES
;
1450 pMutex
= (pthread_mutex_t
*)pCtx
->pInMutex
;
1451 pthread_mutex_lock(pMutex
);
1452 index
= MFC_Decoder_Find_Inbuf(pCtx
, pBuffer
[0]);
1454 pthread_mutex_unlock(pMutex
);
1455 ALOGE("%s: Failed to get index", __func__
);
1456 ret
= VIDEO_ERROR_NOBUFFERS
;
1461 pCtx
->pInbuf
[buf
.index
].bQueued
= VIDEO_TRUE
;
1463 if (pCtx
->bShareInbuf
== VIDEO_TRUE
) {
1464 buf
.memory
= pCtx
->nMemoryType
;
1465 for (i
= 0; i
< nPlanes
; i
++) {
1466 /* V4L2_MEMORY_USERPTR */
1467 buf
.m
.planes
[i
].m
.userptr
= (unsigned long)pBuffer
[i
];
1468 /* V4L2_MEMORY_DMABUF */
1469 buf
.m
.planes
[i
].m
.fd
= pCtx
->pInbuf
[index
].planes
[i
].fd
;
1470 buf
.m
.planes
[i
].length
= pCtx
->pInbuf
[index
].planes
[i
].allocSize
;
1471 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1472 ALOGV("%s: shared inbuf(%d) plane(%d) addr=%p fd=%d len=%d used=%d\n", __func__
,
1474 buf
.m
.planes
[i
].m
.userptr
,
1475 buf
.m
.planes
[i
].m
.fd
,
1476 buf
.m
.planes
[i
].length
,
1477 buf
.m
.planes
[i
].bytesused
);
1480 buf
.memory
= V4L2_MEMORY_MMAP
;
1481 for (i
= 0; i
< nPlanes
; i
++)
1482 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1485 if ((((OMX_BUFFERHEADERTYPE
*)pPrivate
)->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) {
1486 buf
.flags
|= V4L2_BUF_FLAG_LAST_FRAME
;
1487 ALOGV("%s: OMX_BUFFERFLAG_EOS => LAST_FRAME: 0x%x", __func__
,
1488 !!(buf
.flags
& V4L2_BUF_FLAG_LAST_FRAME
));
1491 pCtx
->pInbuf
[buf
.index
].pPrivate
= pPrivate
;
1493 pthread_mutex_unlock(pMutex
);
1495 if (exynos_v4l2_qbuf(pCtx
->hDec
, &buf
) != 0) {
1496 ALOGE("%s: Failed to enqueue input buffer", __func__
);
1497 pthread_mutex_lock(pMutex
);
1498 pCtx
->pInbuf
[buf
.index
].pPrivate
= NULL
;
1499 pCtx
->pInbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1500 pthread_mutex_unlock(pMutex
);
1501 ret
= VIDEO_ERROR_APIFAIL
;
1510 * [Decoder Buffer OPS] Enqueue (Output)
1512 static ExynosVideoErrorType
MFC_Decoder_Enqueue_Outbuf(
1514 unsigned char *pBuffer
[],
1515 unsigned int dataSize
[],
1519 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1520 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1521 pthread_mutex_t
*pMutex
= NULL
;
1523 struct v4l2_plane planes
[VIDEO_DECODER_OUTBUF_PLANES
];
1524 struct v4l2_buffer buf
;
1528 ALOGE("%s: Video context info must be supplied", __func__
);
1529 ret
= VIDEO_ERROR_BADPARAM
;
1533 if (VIDEO_DECODER_OUTBUF_PLANES
< nPlanes
) {
1534 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__
,
1535 VIDEO_DECODER_OUTBUF_PLANES
, nPlanes
);
1536 ret
= VIDEO_ERROR_BADPARAM
;
1540 memset(&buf
, 0, sizeof(buf
));
1541 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1542 buf
.m
.planes
= planes
;
1543 buf
.length
= VIDEO_DECODER_OUTBUF_PLANES
;
1545 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
1546 pthread_mutex_lock(pMutex
);
1547 index
= MFC_Decoder_Find_Outbuf(pCtx
, pBuffer
[0]);
1549 pthread_mutex_unlock(pMutex
);
1550 ALOGE("%s: Failed to get index", __func__
);
1551 ret
= VIDEO_ERROR_NOBUFFERS
;
1555 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_TRUE
;
1557 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
) {
1558 buf
.memory
= pCtx
->nMemoryType
;
1559 for (i
= 0; i
< nPlanes
; i
++) {
1560 /* V4L2_MEMORY_USERPTR */
1561 buf
.m
.planes
[i
].m
.userptr
= (unsigned long)pBuffer
[i
];
1562 /* V4L2_MEMORY_DMABUF */
1563 buf
.m
.planes
[i
].m
.fd
= pCtx
->pOutbuf
[index
].planes
[i
].fd
;
1564 buf
.m
.planes
[i
].length
= pCtx
->pOutbuf
[index
].planes
[i
].allocSize
;
1565 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1566 ALOGV("%s: shared outbuf(%d) plane=%d addr=%p fd=%d len=%d used=%d\n", __func__
,
1568 buf
.m
.planes
[i
].m
.userptr
,
1569 buf
.m
.planes
[i
].m
.fd
,
1570 buf
.m
.planes
[i
].length
,
1571 buf
.m
.planes
[i
].bytesused
);
1574 ALOGV("%s: non-shared outbuf(%d)\n", __func__
, index
);
1575 buf
.memory
= V4L2_MEMORY_MMAP
;
1578 pCtx
->pOutbuf
[buf
.index
].pPrivate
= pPrivate
;
1580 pthread_mutex_unlock(pMutex
);
1582 if (exynos_v4l2_qbuf(pCtx
->hDec
, &buf
) != 0) {
1583 ALOGE("%s: Failed to enqueue output buffer", __func__
);
1584 pthread_mutex_lock(pMutex
);
1585 pCtx
->pOutbuf
[buf
.index
].pPrivate
= NULL
;
1586 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1587 pthread_mutex_unlock(pMutex
);
1588 ret
= VIDEO_ERROR_APIFAIL
;
1597 * [Decoder Buffer OPS] Dequeue (Input)
1599 static ExynosVideoBuffer
*MFC_Decoder_Dequeue_Inbuf(void *pHandle
)
1601 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1602 ExynosVideoBuffer
*pInbuf
= NULL
;
1603 pthread_mutex_t
*pMutex
= NULL
;
1605 struct v4l2_buffer buf
;
1608 ALOGE("%s: Video context info must be supplied", __func__
);
1612 if (pCtx
->bStreamonInbuf
== VIDEO_FALSE
) {
1617 memset(&buf
, 0, sizeof(buf
));
1619 buf
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1621 if (pCtx
->bShareInbuf
== VIDEO_TRUE
)
1622 buf
.memory
= pCtx
->nMemoryType
;
1624 buf
.memory
= V4L2_MEMORY_MMAP
;
1626 if (exynos_v4l2_dqbuf(pCtx
->hDec
, &buf
) != 0) {
1631 pMutex
= (pthread_mutex_t
*)pCtx
->pInMutex
;
1632 pthread_mutex_lock(pMutex
);
1634 pInbuf
= &pCtx
->pInbuf
[buf
.index
];
1635 pCtx
->pInbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1637 if (pCtx
->bStreamonInbuf
== VIDEO_FALSE
)
1640 pthread_mutex_unlock(pMutex
);
1647 * [Decoder Buffer OPS] Dequeue (Output)
1649 static ExynosVideoBuffer
*MFC_Decoder_Dequeue_Outbuf(void *pHandle
)
1651 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1652 ExynosVideoBuffer
*pOutbuf
= NULL
;
1653 pthread_mutex_t
*pMutex
= NULL
;
1655 struct v4l2_buffer buf
;
1659 ALOGE("%s: Video context info must be supplied", __func__
);
1663 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
1668 memset(&buf
, 0, sizeof(buf
));
1669 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1671 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
)
1672 buf
.memory
= pCtx
->nMemoryType
;
1674 buf
.memory
= V4L2_MEMORY_MMAP
;
1676 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
1677 if (exynos_v4l2_dqbuf(pCtx
->hDec
, &buf
) != 0) {
1682 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
1687 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
1688 pthread_mutex_lock(pMutex
);
1690 pOutbuf
= &pCtx
->pOutbuf
[buf
.index
];
1692 exynos_v4l2_g_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS
, &value
);
1696 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DECODING_ONLY
;
1699 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DISPLAY_DECODING
;
1702 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DISPLAY_ONLY
;
1705 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_CHANGE_RESOL
;
1708 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_UNKNOWN
;
1712 switch (buf
.flags
& (0x7 << 3)) {
1713 case V4L2_BUF_FLAG_KEYFRAME
:
1714 pOutbuf
->frameType
= VIDEO_FRAME_I
;
1716 case V4L2_BUF_FLAG_PFRAME
:
1717 pOutbuf
->frameType
= VIDEO_FRAME_P
;
1719 case V4L2_BUF_FLAG_BFRAME
:
1720 pOutbuf
->frameType
= VIDEO_FRAME_B
;
1723 pOutbuf
->frameType
= VIDEO_FRAME_OTHERS
;
1727 pOutbuf
->bQueued
= VIDEO_FALSE
;
1729 pthread_mutex_unlock(pMutex
);
1735 static ExynosVideoErrorType
MFC_Decoder_Clear_Queued_Inbuf(void *pHandle
)
1737 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1738 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1742 ALOGE("%s: Video context info must be supplied", __func__
);
1743 ret
= VIDEO_ERROR_BADPARAM
;
1747 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
1748 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
1755 static ExynosVideoErrorType
MFC_Decoder_Clear_Queued_Outbuf(void *pHandle
)
1757 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1758 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1762 ALOGE("%s: Video context info must be supplied", __func__
);
1763 ret
= VIDEO_ERROR_BADPARAM
;
1767 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
1768 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
1776 * [Decoder Buffer OPS] FindIndex (Output)
1778 static int MFC_Decoder_FindEmpty_Outbuf(void *pHandle
)
1780 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1784 ALOGE("%s: Video context info must be supplied", __func__
);
1788 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1789 if ((pCtx
->pOutbuf
[nIndex
].bQueued
== VIDEO_FALSE
) &&
1790 (pCtx
->pOutbuf
[nIndex
].bSlotUsed
== VIDEO_FALSE
))
1794 if (nIndex
== pCtx
->nOutbufs
)
1802 * [Decoder Buffer OPS] BufferIndexFree (Output)
1804 void MFC_Decoder_BufferIndexFree_Outbuf(void *pHandle
, PrivateDataShareBuffer
*pPDSB
, int index
)
1806 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1809 ALOGV("De-queue buf.index:%d", index
);
1810 ALOGV("pOutbuf fd:%d", pCtx
->pOutbuf
[index
].planes
[0].fd
);
1812 if (pCtx
->pOutbuf
[index
].nIndexUseCnt
== 0) {
1813 pCtx
->pOutbuf
[index
].bSlotUsed
= VIDEO_FALSE
;
1816 for (i
= 0; pPDSB
->dpbFD
[i
].fd
> -1; i
++) {
1817 ALOGV("pPDSB->dpbFD[%d].fd:%d", i
, pPDSB
->dpbFD
[i
].fd
);
1818 for (j
= 0; pCtx
->nOutbufs
> j
; j
++)
1819 if (pPDSB
->dpbFD
[i
].fd
== pCtx
->pOutbuf
[j
].planes
[0].fd
) {
1820 if (pCtx
->pOutbuf
[j
].bQueued
== VIDEO_FALSE
) {
1821 if (pCtx
->pOutbuf
[j
].nIndexUseCnt
> 0)
1822 pCtx
->pOutbuf
[j
].nIndexUseCnt
--;
1823 } else if(pCtx
->pOutbuf
[j
].bQueued
== VIDEO_TRUE
) {
1824 if (pCtx
->pOutbuf
[j
].nIndexUseCnt
> 1) {
1825 /* The buffer being used as the reference buffer came again. */
1826 pCtx
->pOutbuf
[j
].nIndexUseCnt
--;
1828 /* Reference DPB buffer is internally reused. */
1831 ALOGV("dec FD:%d, pCtx->pOutbuf[%d].nIndexUseCnt:%d", pPDSB
->dpbFD
[i
].fd
, j
, pCtx
->pOutbuf
[j
].nIndexUseCnt
);
1832 if ((pCtx
->pOutbuf
[j
].nIndexUseCnt
== 0) &&
1833 (pCtx
->pOutbuf
[j
].bQueued
== VIDEO_FALSE
)) {
1834 pCtx
->pOutbuf
[j
].bSlotUsed
= VIDEO_FALSE
;
1838 memset((char *)pPDSB
, -1, sizeof(PrivateDataShareBuffer
));
1844 * [Decoder Buffer OPS] ExtensionEnqueue (Output)
1846 static ExynosVideoErrorType
MFC_Decoder_ExtensionEnqueue_Outbuf(
1848 unsigned char *pBuffer
[],
1849 unsigned int *pFd
[],
1850 unsigned int allocLen
[],
1851 unsigned int dataSize
[],
1855 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1856 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1857 pthread_mutex_t
*pMutex
= NULL
;
1859 struct v4l2_plane planes
[VIDEO_DECODER_OUTBUF_PLANES
];
1860 struct v4l2_buffer buf
;
1864 ALOGE("%s: Video context info must be supplied", __func__
);
1865 ret
= VIDEO_ERROR_BADPARAM
;
1869 if (VIDEO_DECODER_OUTBUF_PLANES
< nPlanes
) {
1870 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__
,
1871 VIDEO_DECODER_OUTBUF_PLANES
, nPlanes
);
1872 ret
= VIDEO_ERROR_BADPARAM
;
1876 memset(&buf
, 0, sizeof(buf
));
1877 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1878 buf
.m
.planes
= planes
;
1879 buf
.length
= VIDEO_DECODER_OUTBUF_PLANES
;
1881 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
1882 pthread_mutex_lock(pMutex
);
1884 index
= MFC_Decoder_Find_Outbuf(pCtx
, pBuffer
[0]);
1886 ALOGV("%s: Failed to find index", __func__
);
1887 index
= MFC_Decoder_FindEmpty_Outbuf(pCtx
);
1889 pthread_mutex_unlock(pMutex
);
1890 ALOGE("%s: Failed to get index", __func__
);
1891 ret
= VIDEO_ERROR_NOBUFFERS
;
1897 ALOGV("En-queue index:%d pCtx->pOutbuf[buf.index].bQueued:%d, pFd[0]:%d",
1898 index
, pCtx
->pOutbuf
[buf
.index
].bQueued
, pFd
[0]);
1899 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_TRUE
;
1900 pCtx
->pOutbuf
[buf
.index
].bSlotUsed
= VIDEO_TRUE
;
1902 buf
.memory
= pCtx
->nMemoryType
;
1903 for (i
= 0; i
< nPlanes
; i
++) {
1904 /* V4L2_MEMORY_USERPTR */
1905 buf
.m
.planes
[i
].m
.userptr
= (unsigned long)pBuffer
[i
];
1906 /* V4L2_MEMORY_DMABUF */
1907 buf
.m
.planes
[i
].m
.fd
= pFd
[i
];
1908 buf
.m
.planes
[i
].length
= allocLen
[i
];
1909 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1911 /* Temporary storage for Dequeue */
1912 pCtx
->pOutbuf
[buf
.index
].planes
[i
].addr
= (unsigned long)pBuffer
[i
];
1913 pCtx
->pOutbuf
[buf
.index
].planes
[i
].fd
= (unsigned int)pFd
[i
];
1914 pCtx
->pOutbuf
[buf
.index
].planes
[i
].allocSize
= allocLen
[i
];
1916 ALOGV("%s: shared outbuf(%d) plane=%d addr=0x%x fd=%d len=%d used=%d\n",
1918 (void*)buf
.m
.planes
[i
].m
.userptr
, buf
.m
.planes
[i
].m
.fd
,
1919 buf
.m
.planes
[i
].length
, buf
.m
.planes
[i
].bytesused
);
1922 pCtx
->pOutbuf
[buf
.index
].pPrivate
= pPrivate
;
1923 pCtx
->pOutbuf
[buf
.index
].nIndexUseCnt
++;
1925 pthread_mutex_unlock(pMutex
);
1927 if (exynos_v4l2_qbuf(pCtx
->hDec
, &buf
) != 0) {
1928 ALOGE("%s: Failed to enqueue output buffer", __func__
);
1929 pthread_mutex_lock(pMutex
);
1930 pCtx
->pOutbuf
[buf
.index
].nIndexUseCnt
--;
1931 pCtx
->pOutbuf
[buf
.index
].pPrivate
= NULL
;
1932 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1933 if (pCtx
->pOutbuf
[buf
.index
].nIndexUseCnt
== 0)
1934 pCtx
->pOutbuf
[buf
.index
].bSlotUsed
= VIDEO_FALSE
;
1935 pthread_mutex_unlock(pMutex
);
1936 ret
= VIDEO_ERROR_APIFAIL
;
1945 * [Decoder Buffer OPS] ExtensionDequeue (Output)
1947 static ExynosVideoErrorType
MFC_Decoder_ExtensionDequeue_Outbuf(
1949 ExynosVideoBuffer
*pVideoBuffer
)
1951 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
1952 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1953 pthread_mutex_t
*pMutex
= NULL
;
1954 ExynosVideoBuffer
*pOutbuf
= NULL
;
1955 PrivateDataShareBuffer
*pPDSB
= NULL
;
1956 struct v4l2_buffer buf
;
1960 ALOGE("%s: Video context info must be supplied", __func__
);
1961 ret
= VIDEO_ERROR_BADPARAM
;
1965 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
1967 ret
= VIDEO_ERROR_APIFAIL
;
1971 memset(&buf
, 0, sizeof(buf
));
1972 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1974 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
)
1975 buf
.memory
= pCtx
->nMemoryType
;
1977 buf
.memory
= V4L2_MEMORY_MMAP
;
1979 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
1980 if (exynos_v4l2_dqbuf(pCtx
->hDec
, &buf
) != 0) {
1982 ret
= VIDEO_ERROR_APIFAIL
;
1986 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
1987 pthread_mutex_lock(pMutex
);
1989 pOutbuf
= &pCtx
->pOutbuf
[buf
.index
];
1990 exynos_v4l2_g_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS
, &value
);
1994 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DECODING_ONLY
;
1997 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DISPLAY_DECODING
;
2000 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_DISPLAY_ONLY
;
2003 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_CHANGE_RESOL
;
2006 pOutbuf
->displayStatus
= VIDEO_FRAME_STATUS_UNKNOWN
;
2010 switch (buf
.flags
& (0x7 << 3)) {
2011 case V4L2_BUF_FLAG_KEYFRAME
:
2012 pOutbuf
->frameType
= VIDEO_FRAME_I
;
2014 case V4L2_BUF_FLAG_PFRAME
:
2015 pOutbuf
->frameType
= VIDEO_FRAME_P
;
2017 case V4L2_BUF_FLAG_BFRAME
:
2018 pOutbuf
->frameType
= VIDEO_FRAME_B
;
2021 pOutbuf
->frameType
= VIDEO_FRAME_OTHERS
;
2025 pPDSB
= ((PrivateDataShareBuffer
*)pCtx
->nPrivateDataShareAddress
) + buf
.index
;
2026 if (pCtx
->pOutbuf
[buf
.index
].bQueued
== VIDEO_TRUE
) {
2027 memcpy(pVideoBuffer
, pOutbuf
, sizeof(ExynosVideoBuffer
));
2028 memcpy((char *)(&(pVideoBuffer
->PDSB
)), (char *)pPDSB
, sizeof(PrivateDataShareBuffer
));
2030 ret
= VIDEO_ERROR_NOBUFFERS
;
2031 ALOGV("%s :: %d", __FUNCTION__
, __LINE__
);
2034 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
2035 MFC_Decoder_BufferIndexFree_Outbuf(pHandle
, pPDSB
, buf
.index
);
2037 pthread_mutex_unlock(pMutex
);
2044 * [Decoder Buffer OPS] Enable Dynamic DPB
2046 static ExynosVideoErrorType
MFC_Decoder_Enable_DynamicDPB(void *pHandle
)
2048 ExynosVideoDecContext
*pCtx
= (ExynosVideoDecContext
*)pHandle
;
2049 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
2052 ALOGE("%s: Video context info must be supplied", __func__
);
2053 ret
= VIDEO_ERROR_BADPARAM
;
2057 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE
, 1) != 0) {
2058 ret
= VIDEO_ERROR_APIFAIL
;
2062 if (exynos_v4l2_s_ctrl(pCtx
->hDec
, V4L2_CID_MPEG_MFC_SET_USER_SHARED_HANDLE
, pCtx
->nPrivateDataShareFD
) != 0) {
2063 ret
= VIDEO_ERROR_APIFAIL
;
2072 * [Decoder OPS] Common
2074 static ExynosVideoDecOps defDecOps
= {
2076 .Init
= MFC_Decoder_Init
,
2077 .Finalize
= MFC_Decoder_Finalize
,
2078 .Set_DisplayDelay
= MFC_Decoder_Set_DisplayDelay
,
2079 .Set_IFrameDecoding
= MFC_Decoder_Set_IFrameDecoding
,
2080 .Enable_PackedPB
= MFC_Decoder_Enable_PackedPB
,
2081 .Enable_LoopFilter
= MFC_Decoder_Enable_LoopFilter
,
2082 .Enable_SliceMode
= MFC_Decoder_Enable_SliceMode
,
2083 .Get_ActualBufferCount
= MFC_Decoder_Get_ActualBufferCount
,
2084 .Set_FrameTag
= MFC_Decoder_Set_FrameTag
,
2085 .Get_FrameTag
= MFC_Decoder_Get_FrameTag
,
2086 .Enable_SEIParsing
= MFC_Decoder_Enable_SEIParsing
,
2087 .Get_FramePackingInfo
= MFC_Decoder_Get_FramePackingInfo
,
2091 * [Decoder Buffer OPS] Input
2093 static ExynosVideoDecBufferOps defInbufOps
= {
2095 .Enable_Cacheable
= MFC_Decoder_Enable_Cacheable_Inbuf
,
2096 .Set_Shareable
= MFC_Decoder_Set_Shareable_Inbuf
,
2098 .Set_Geometry
= MFC_Decoder_Set_Geometry_Inbuf
,
2099 .Get_Geometry
= NULL
,
2100 .Setup
= MFC_Decoder_Setup_Inbuf
,
2101 .Run
= MFC_Decoder_Run_Inbuf
,
2102 .Stop
= MFC_Decoder_Stop_Inbuf
,
2103 .Enqueue
= MFC_Decoder_Enqueue_Inbuf
,
2104 .Enqueue_All
= NULL
,
2105 .Dequeue
= MFC_Decoder_Dequeue_Inbuf
,
2106 .Register
= MFC_Decoder_Register_Inbuf
,
2107 .Clear_RegisteredBuffer
= MFC_Decoder_Clear_RegisteredBuffer_Inbuf
,
2108 .Clear_Queue
= MFC_Decoder_Clear_Queued_Inbuf
,
2112 * [Decoder Buffer OPS] Output
2114 static ExynosVideoDecBufferOps defOutbufOps
= {
2116 .Enable_Cacheable
= MFC_Decoder_Enable_Cacheable_Outbuf
,
2117 .Set_Shareable
= MFC_Decoder_Set_Shareable_Outbuf
,
2118 .Get_Buffer
= MFC_Decoder_Get_Buffer_Outbuf
,
2119 .Set_Geometry
= MFC_Decoder_Set_Geometry_Outbuf
,
2120 .Get_Geometry
= MFC_Decoder_Get_Geometry_Outbuf
,
2121 .Setup
= MFC_Decoder_Setup_Outbuf
,
2122 .Run
= MFC_Decoder_Run_Outbuf
,
2123 .Stop
= MFC_Decoder_Stop_Outbuf
,
2124 .Enqueue
= MFC_Decoder_Enqueue_Outbuf
,
2125 .Enqueue_All
= NULL
,
2126 .Dequeue
= MFC_Decoder_Dequeue_Outbuf
,
2127 .Register
= MFC_Decoder_Register_Outbuf
,
2128 .Clear_RegisteredBuffer
= MFC_Decoder_Clear_RegisteredBuffer_Outbuf
,
2129 .Clear_Queue
= MFC_Decoder_Clear_Queued_Outbuf
,
2130 .ExtensionEnqueue
= MFC_Decoder_ExtensionEnqueue_Outbuf
,
2131 .ExtensionDequeue
= MFC_Decoder_ExtensionDequeue_Outbuf
,
2132 .Enable_DynamicDPB
= MFC_Decoder_Enable_DynamicDPB
,
2135 int Exynos_Video_Register_Decoder(
2136 ExynosVideoDecOps
*pDecOps
,
2137 ExynosVideoDecBufferOps
*pInbufOps
,
2138 ExynosVideoDecBufferOps
*pOutbufOps
)
2140 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
2142 if ((pDecOps
== NULL
) || (pInbufOps
== NULL
) || (pOutbufOps
== NULL
)) {
2143 ret
= VIDEO_ERROR_BADPARAM
;
2147 defDecOps
.nSize
= sizeof(defDecOps
);
2148 defInbufOps
.nSize
= sizeof(defInbufOps
);
2149 defOutbufOps
.nSize
= sizeof(defOutbufOps
);
2151 memcpy((char *)pDecOps
+ sizeof(pDecOps
->nSize
), (char *)&defDecOps
+ sizeof(defDecOps
.nSize
),
2152 pDecOps
->nSize
- sizeof(pDecOps
->nSize
));
2154 memcpy((char *)pInbufOps
+ sizeof(pInbufOps
->nSize
), (char *)&defInbufOps
+ sizeof(defInbufOps
.nSize
),
2155 pInbufOps
->nSize
- sizeof(pInbufOps
->nSize
));
2157 memcpy((char *)pOutbufOps
+ sizeof(pOutbufOps
->nSize
), (char *)&defOutbufOps
+ sizeof(defOutbufOps
.nSize
),
2158 pOutbufOps
->nSize
- sizeof(pOutbufOps
->nSize
));