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 ExynosVideoEncoder.c
21 * @author Hyeyeon Chung (hyeon.chung@samsung.com)
22 * @author Jinsung Yang (jsgood.yang@samsung.com)
23 * @author Yunji Kim (yunji.kim@samsung.com)
26 * 2012.02.09: Initial Version
35 #include <sys/types.h>
37 #include <sys/ioctl.h>
43 #include "ExynosVideoApi.h"
44 #include "ExynosVideoEnc.h"
46 /* #define LOG_NDEBUG 0 */
47 #define LOG_TAG "ExynosVideoEncoder"
48 #include <utils/Log.h>
50 #define MAX_CTRL_NUM 91
51 #define H264_CTRL_NUM 91
52 #define MPEG4_CTRL_NUM 26
53 #define H263_CTRL_NUM 18
56 * [Common] __CodingType_To_V4L2PixelFormat
58 static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType
)
60 unsigned int pixelformat
= V4L2_PIX_FMT_H264
;
63 case VIDEO_CODING_AVC
:
64 pixelformat
= V4L2_PIX_FMT_H264
;
66 case VIDEO_CODING_MPEG4
:
67 pixelformat
= V4L2_PIX_FMT_MPEG4
;
69 case VIDEO_CODING_VP8
:
70 pixelformat
= V4L2_PIX_FMT_VP8
;
72 case VIDEO_CODING_H263
:
73 pixelformat
= V4L2_PIX_FMT_H263
;
75 case VIDEO_CODING_VC1
:
76 pixelformat
= V4L2_PIX_FMT_VC1_ANNEX_G
;
78 case VIDEO_CODING_VC1_RCV
:
79 pixelformat
= V4L2_PIX_FMT_VC1_ANNEX_L
;
81 case VIDEO_CODING_MPEG2
:
82 pixelformat
= V4L2_PIX_FMT_MPEG2
;
85 pixelformat
= V4L2_PIX_FMT_H264
;
93 * [Common] __ColorFormatType_To_V4L2PixelFormat
95 static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType
)
97 unsigned int pixelformat
= V4L2_PIX_FMT_NV12M
;
99 switch (colorFormatType
) {
100 case VIDEO_COLORFORMAT_NV12_TILED
:
101 pixelformat
= V4L2_PIX_FMT_NV12MT_16X16
;
103 case VIDEO_COLORFORMAT_NV21
:
104 pixelformat
= V4L2_PIX_FMT_NV21M
;
106 case VIDEO_COLORFORMAT_NV12
:
108 pixelformat
= V4L2_PIX_FMT_NV12M
;
118 static void *MFC_Encoder_Init(int nMemoryType
)
120 ExynosVideoEncContext
*pCtx
= NULL
;
121 pthread_mutex_t
*pMutex
= NULL
;
122 int needCaps
= (V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_VIDEO_OUTPUT
| V4L2_CAP_STREAMING
);
124 pCtx
= (ExynosVideoEncContext
*)malloc(sizeof(*pCtx
));
126 ALOGE("%s: Failed to allocate encoder context buffer", __func__
);
127 goto EXIT_ALLOC_FAIL
;
130 memset(pCtx
, 0, sizeof(*pCtx
));
132 pCtx
->hEnc
= exynos_v4l2_open_devname(VIDEO_ENCODER_NAME
, O_RDWR
, 0);
133 if (pCtx
->hEnc
< 0) {
134 ALOGE("%s: Failed to open encoder device", __func__
);
138 if (!exynos_v4l2_querycap(pCtx
->hEnc
, needCaps
)) {
139 ALOGE("%s: Failed to querycap", __func__
);
140 goto EXIT_QUERYCAP_FAIL
;
143 pCtx
->bStreamonInbuf
= VIDEO_FALSE
;
144 pCtx
->bStreamonOutbuf
= VIDEO_FALSE
;
146 pCtx
->nMemoryType
= nMemoryType
;
148 pMutex
= (pthread_mutex_t
*)malloc(sizeof(pthread_mutex_t
));
149 if (pMutex
== NULL
) {
150 ALOGE("%s: Failed to allocate mutex about input buffer", __func__
);
151 goto EXIT_QUERYCAP_FAIL
;
153 if (pthread_mutex_init(pMutex
, NULL
) != 0) {
155 goto EXIT_QUERYCAP_FAIL
;
157 pCtx
->pInMutex
= (void*)pMutex
;
159 pMutex
= (pthread_mutex_t
*)malloc(sizeof(pthread_mutex_t
));
160 if (pMutex
== NULL
) {
161 ALOGE("%s: Failed to allocate mutex about output buffer", __func__
);
162 goto EXIT_QUERYCAP_FAIL
;
164 if (pthread_mutex_init(pMutex
, NULL
) != 0) {
166 goto EXIT_QUERYCAP_FAIL
;
168 pCtx
->pOutMutex
= (void*)pMutex
;
173 if (pCtx
->pInMutex
!= NULL
) {
174 pthread_mutex_destroy(pCtx
->pInMutex
);
175 free(pCtx
->pInMutex
);
178 if (pCtx
->pOutMutex
!= NULL
) {
179 pthread_mutex_destroy(pCtx
->pOutMutex
);
180 free(pCtx
->pOutMutex
);
193 * [Encoder OPS] Finalize
195 static ExynosVideoErrorType
MFC_Encoder_Finalize(void *pHandle
)
197 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
198 ExynosVideoPlane
*pVideoPlane
= NULL
;
199 pthread_mutex_t
*pMutex
= NULL
;
200 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
204 ALOGE("%s: Video context info must be supplied", __func__
);
205 ret
= VIDEO_ERROR_BADPARAM
;
209 if (pCtx
->pOutMutex
!= NULL
) {
210 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
211 pthread_mutex_destroy(pMutex
);
213 pCtx
->pOutMutex
= NULL
;
216 if (pCtx
->pInMutex
!= NULL
) {
217 pMutex
= (pthread_mutex_t
*)pCtx
->pInMutex
;
218 pthread_mutex_destroy(pMutex
);
220 pCtx
->pInMutex
= NULL
;
223 if (pCtx
->bShareInbuf
== VIDEO_FALSE
) {
224 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
225 for (j
= 0; j
< VIDEO_ENCODER_INBUF_PLANES
; j
++) {
226 pVideoPlane
= &pCtx
->pInbuf
[i
].planes
[j
];
227 if (pVideoPlane
->addr
!= NULL
) {
228 munmap(pVideoPlane
->addr
, pVideoPlane
->allocSize
);
229 pVideoPlane
->addr
= NULL
;
230 pVideoPlane
->allocSize
= 0;
231 pVideoPlane
->dataSize
= 0;
234 pCtx
->pInbuf
[i
].pGeometry
= NULL
;
235 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
236 pCtx
->pInbuf
[i
].bRegistered
= VIDEO_FALSE
;
241 if (pCtx
->bShareOutbuf
== VIDEO_FALSE
) {
242 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
243 for (j
= 0; j
< VIDEO_ENCODER_OUTBUF_PLANES
; j
++) {
244 pVideoPlane
= &pCtx
->pOutbuf
[i
].planes
[j
];
245 if (pVideoPlane
->addr
!= NULL
) {
246 munmap(pVideoPlane
->addr
, pVideoPlane
->allocSize
);
247 pVideoPlane
->addr
= NULL
;
248 pVideoPlane
->allocSize
= 0;
249 pVideoPlane
->dataSize
= 0;
252 pCtx
->pOutbuf
[i
].pGeometry
= NULL
;
253 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
254 pCtx
->pOutbuf
[i
].bRegistered
= VIDEO_FALSE
;
259 if (pCtx
->pInbuf
!= NULL
)
262 if (pCtx
->pOutbuf
!= NULL
)
275 * [Encoder OPS] Set Extended Control
277 static ExynosVideoErrorType
MFC_Encoder_Set_EncParam (
279 ExynosVideoEncParam
*pEncParam
)
281 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
282 ExynosVideoEncInitParam
*pInitParam
= NULL
;
283 ExynosVideoEncCommonParam
*pCommonParam
= NULL
;
285 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
288 struct v4l2_ext_control ext_ctrl
[MAX_CTRL_NUM
];
289 struct v4l2_ext_controls ext_ctrls
;
291 if ((pCtx
== NULL
) || (pEncParam
== NULL
)) {
292 ALOGE("%s: Video context info must be supplied", __func__
);
293 ret
= VIDEO_ERROR_BADPARAM
;
297 pInitParam
= &pEncParam
->initParam
;
298 pCommonParam
= &pEncParam
->commonParam
;
300 /* common parameters */
301 ext_ctrl
[0].id
= V4L2_CID_MPEG_VIDEO_GOP_SIZE
;
302 ext_ctrl
[0].value
= pCommonParam
->IDRPeriod
;
303 ext_ctrl
[1].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE
;
304 ext_ctrl
[1].value
= pCommonParam
->SliceMode
; /* 0: one, 1: fixed #mb, 3: fixed #bytes */
305 ext_ctrl
[2].id
= V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB
;
306 ext_ctrl
[2].value
= pCommonParam
->RandomIntraMBRefresh
;
307 ext_ctrl
[3].id
= V4L2_CID_MPEG_MFC51_VIDEO_PADDING
;
308 ext_ctrl
[3].value
= pCommonParam
->PadControlOn
;
309 ext_ctrl
[4].id
= V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV
;
310 ext_ctrl
[4].value
= pCommonParam
->CrPadVal
;
311 ext_ctrl
[4].value
|= (pCommonParam
->CbPadVal
<< 8);
312 ext_ctrl
[4].value
|= (pCommonParam
->LumaPadVal
<< 16);
313 ext_ctrl
[5].id
= V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
;
314 ext_ctrl
[5].value
= pCommonParam
->EnableFRMRateControl
;
315 ext_ctrl
[6].id
= V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE
;
316 ext_ctrl
[6].value
= pCommonParam
->EnableMBRateControl
;
317 ext_ctrl
[7].id
= V4L2_CID_MPEG_VIDEO_BITRATE
;
319 /* FIXME temporary fix */
320 if (pCommonParam
->Bitrate
)
321 ext_ctrl
[7].value
= pCommonParam
->Bitrate
;
323 ext_ctrl
[7].value
= 1; /* just for testing Movie studio */
325 /* codec specific parameters */
326 switch (pEncParam
->eCompressionFormat
) {
327 case VIDEO_CODING_AVC
:
329 ExynosVideoEncH264Param
*pH264Param
= &pEncParam
->codecParam
.h264
;
331 /* common parameters but id is depends on codec */
332 ext_ctrl
[8].id
= V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP
;
333 ext_ctrl
[8].value
= pCommonParam
->FrameQp
;
334 ext_ctrl
[9].id
= V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP
;
335 ext_ctrl
[9].value
= pCommonParam
->FrameQp_P
;
336 ext_ctrl
[10].id
= V4L2_CID_MPEG_VIDEO_H264_MAX_QP
;
337 ext_ctrl
[10].value
= pCommonParam
->QSCodeMax
;
338 ext_ctrl
[11].id
= V4L2_CID_MPEG_VIDEO_H264_MIN_QP
;
339 ext_ctrl
[11].value
= pCommonParam
->QSCodeMin
;
340 ext_ctrl
[12].id
= V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF
;
341 ext_ctrl
[12].value
= pCommonParam
->CBRPeriodRf
;
343 /* H.264 specific parameters */
344 switch (pCommonParam
->SliceMode
) {
346 ext_ctrl
[13].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB
;
347 ext_ctrl
[13].value
= 1; /* default */
348 ext_ctrl
[14].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES
;
349 ext_ctrl
[14].value
= 2800; /* based on MFC6.x */
352 ext_ctrl
[13].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB
;
353 ext_ctrl
[13].value
= pH264Param
->SliceArgument
;
354 ext_ctrl
[14].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES
;
355 ext_ctrl
[14].value
= 2800; /* based on MFC6.x */
358 ext_ctrl
[13].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB
;
359 ext_ctrl
[13].value
= 1; /* default */
360 ext_ctrl
[14].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES
;
361 ext_ctrl
[14].value
= pH264Param
->SliceArgument
;
367 ext_ctrl
[15].id
= V4L2_CID_MPEG_VIDEO_H264_PROFILE
;
368 ext_ctrl
[15].value
= pH264Param
->ProfileIDC
;
369 ext_ctrl
[16].id
= V4L2_CID_MPEG_VIDEO_H264_LEVEL
;
370 ext_ctrl
[16].value
= pH264Param
->LevelIDC
;
371 ext_ctrl
[17].id
= V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P
;
372 ext_ctrl
[17].value
= pH264Param
->NumberRefForPframes
;
374 * It should be set using h264Param->NumberBFrames after being handled by appl.
376 ext_ctrl
[18].id
= V4L2_CID_MPEG_VIDEO_B_FRAMES
;
377 ext_ctrl
[18].value
= pH264Param
->NumberBFrames
;
378 ext_ctrl
[19].id
= V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE
;
379 ext_ctrl
[19].value
= pH264Param
->LoopFilterDisable
;
380 ext_ctrl
[20].id
= V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA
;
381 ext_ctrl
[20].value
= pH264Param
->LoopFilterAlphaC0Offset
;
382 ext_ctrl
[21].id
= V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA
;
383 ext_ctrl
[21].value
= pH264Param
->LoopFilterBetaOffset
;
384 ext_ctrl
[22].id
= V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE
;
385 ext_ctrl
[22].value
= pH264Param
->SymbolMode
;
386 ext_ctrl
[23].id
= V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE
;
387 ext_ctrl
[23].value
= pH264Param
->PictureInterlace
;
388 ext_ctrl
[24].id
= V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM
;
389 ext_ctrl
[24].value
= pH264Param
->Transform8x8Mode
;
390 ext_ctrl
[25].id
= V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE
;
391 ext_ctrl
[25].value
= pH264Param
->FrameRate
;
392 ext_ctrl
[26].id
= V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP
;
393 ext_ctrl
[26].value
= pH264Param
->FrameQp_B
;
394 ext_ctrl
[27].id
= V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK
;
395 ext_ctrl
[27].value
= pH264Param
->DarkDisable
;
396 ext_ctrl
[28].id
= V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH
;
397 ext_ctrl
[28].value
= pH264Param
->SmoothDisable
;
398 ext_ctrl
[29].id
= V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC
;
399 ext_ctrl
[29].value
= pH264Param
->StaticDisable
;
400 ext_ctrl
[30].id
= V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY
;
401 ext_ctrl
[30].value
= pH264Param
->ActivityDisable
;
403 /* doesn't have to be set */
404 ext_ctrl
[31].id
= V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
;
405 ext_ctrl
[31].value
= 1;
406 ext_ctrl
[32].id
= V4L2_CID_MPEG_VIDEO_H264_I_PERIOD
;
407 ext_ctrl
[32].value
= 0;
408 ext_ctrl
[33].id
= V4L2_CID_MPEG_VIDEO_VBV_SIZE
;
409 ext_ctrl
[33].value
= 0;
410 ext_ctrl
[34].id
= V4L2_CID_MPEG_VIDEO_HEADER_MODE
;
411 ext_ctrl
[34].value
= V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE
; /* 0: seperated header, 1: header + first frame */
412 ext_ctrl
[35].id
= V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE
;
413 ext_ctrl
[35].value
= 0;
414 ext_ctrl
[36].id
= V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC
;
415 ext_ctrl
[36].value
= V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED
;
416 ext_ctrl
[37].id
= V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH
;
417 ext_ctrl
[37].value
= 0;
418 ext_ctrl
[38].id
= V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT
;
419 ext_ctrl
[38].value
= 0;
421 /* Initial parameters : Frame Skip */
422 switch (pInitParam
->FrameSkip
) {
423 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT
:
424 ext_ctrl
[39].id
= V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
;
425 ext_ctrl
[39].value
= V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT
;
427 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT
:
428 ext_ctrl
[39].id
= V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
;
429 ext_ctrl
[39].value
= V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT
;
432 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
433 ext_ctrl
[39].id
= V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
;
434 ext_ctrl
[39].value
= V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED
;
438 /* SVC is not supported yet */
439 ext_ctrl
[40].id
= V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING
;
440 ext_ctrl
[40].value
= 0;
441 ext_ctrl
[41].id
= V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE
;
442 ext_ctrl
[41].value
= V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B
;
443 ext_ctrl
[42].id
= V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER
;
444 ext_ctrl
[42].value
= 3;
445 ext_ctrl
[43].id
= V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP
;
446 ext_ctrl
[43].value
= (0 << 16 | 0);
447 ext_ctrl
[44].id
= V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP
;
448 ext_ctrl
[44].value
= (1 << 16 | 0);
449 ext_ctrl
[45].id
= V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP
;
450 ext_ctrl
[45].value
= (2 << 16 | 0);
452 ext_ctrl
[46].id
= V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING
;
453 ext_ctrl
[46].value
= 0;
454 ext_ctrl
[47].id
= V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0
;
455 ext_ctrl
[47].value
= 0;
456 ext_ctrl
[48].id
= V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE
;
457 ext_ctrl
[48].value
= V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE
;
459 /* FMO is not supported yet */
460 ext_ctrl
[49].id
= V4L2_CID_MPEG_VIDEO_H264_FMO
;
461 ext_ctrl
[49].value
= 0;
462 ext_ctrl
[50].id
= V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE
;
463 ext_ctrl
[50].value
= V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES
;
464 ext_ctrl
[51].id
= V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP
;
465 ext_ctrl
[51].value
= 4;
466 ext_ctrl
[52].id
= V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH
;
467 ext_ctrl
[52].value
= (0 << 30 | 0);
468 ext_ctrl
[53].id
= V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH
;
469 ext_ctrl
[53].value
= (1 << 30 | 0);
470 ext_ctrl
[54].id
= V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH
;
471 ext_ctrl
[54].value
= (2 << 30 | 0);
472 ext_ctrl
[55].id
= V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH
;
473 ext_ctrl
[55].value
= (3 << 30 | 0);
474 ext_ctrl
[56].id
= V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION
;
475 ext_ctrl
[56].value
= V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT
;
476 ext_ctrl
[57].id
= V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE
;
477 ext_ctrl
[57].value
= 0;
479 /* ASO is not supported yet */
480 ext_ctrl
[58].id
= V4L2_CID_MPEG_VIDEO_H264_ASO
;
481 ext_ctrl
[58].value
= 0;
482 for (i
= 0; i
< 32; i
++) {
483 ext_ctrl
[59 + i
].id
= V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER
;
484 ext_ctrl
[59 + i
].value
= (i
<< 16 | 0);
487 ext_ctrls
.count
= H264_CTRL_NUM
;
491 case VIDEO_CODING_MPEG4
:
493 ExynosVideoEncMpeg4Param
*pMpeg4Param
= &pEncParam
->codecParam
.mpeg4
;
495 /* common parameters but id is depends on codec */
496 ext_ctrl
[8].id
= V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP
;
497 ext_ctrl
[8].value
= pCommonParam
->FrameQp
;
498 ext_ctrl
[9].id
= V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP
;
499 ext_ctrl
[9].value
= pCommonParam
->FrameQp_P
;
500 ext_ctrl
[10].id
= V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP
;
501 ext_ctrl
[10].value
= pCommonParam
->QSCodeMax
;
502 ext_ctrl
[11].id
= V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP
;
503 ext_ctrl
[11].value
= pCommonParam
->QSCodeMin
;
504 ext_ctrl
[12].id
= V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF
;
505 ext_ctrl
[12].value
= pCommonParam
->CBRPeriodRf
;
507 /* MPEG4 specific parameters */
508 switch (pCommonParam
->SliceMode
) {
510 ext_ctrl
[13].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB
;
511 ext_ctrl
[13].value
= 1; /* default */
512 ext_ctrl
[14].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES
;
513 ext_ctrl
[14].value
= 2800; /* based on MFC6.x */
516 ext_ctrl
[13].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB
;
517 ext_ctrl
[13].value
= pMpeg4Param
->SliceArgument
;
518 ext_ctrl
[14].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES
;
519 ext_ctrl
[14].value
= 2800; /* based on MFC6.x */
522 ext_ctrl
[13].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB
;
523 ext_ctrl
[13].value
= 1; /* default */
524 ext_ctrl
[14].id
= V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES
;
525 ext_ctrl
[14].value
= pMpeg4Param
->SliceArgument
;
531 ext_ctrl
[15].id
= V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE
;
532 ext_ctrl
[15].value
= pMpeg4Param
->ProfileIDC
;
533 ext_ctrl
[16].id
= V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL
;
534 ext_ctrl
[16].value
= pMpeg4Param
->LevelIDC
;
535 ext_ctrl
[17].id
= V4L2_CID_MPEG_VIDEO_MPEG4_QPEL
;
536 ext_ctrl
[17].value
= pMpeg4Param
->DisableQpelME
;
539 * It should be set using mpeg4Param->NumberBFrames after being handled by appl.
541 ext_ctrl
[18].id
= V4L2_CID_MPEG_VIDEO_B_FRAMES
;
542 ext_ctrl
[18].value
= pMpeg4Param
->NumberBFrames
;
544 ext_ctrl
[19].id
= V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES
;
545 ext_ctrl
[19].value
= pMpeg4Param
->TimeIncreamentRes
;
546 ext_ctrl
[20].id
= V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA
;
547 ext_ctrl
[20].value
= pMpeg4Param
->VopTimeIncreament
;
548 ext_ctrl
[21].id
= V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP
;
549 ext_ctrl
[21].value
= pMpeg4Param
->FrameQp_B
;
550 ext_ctrl
[22].id
= V4L2_CID_MPEG_VIDEO_VBV_SIZE
;
551 ext_ctrl
[22].value
= 0;
552 ext_ctrl
[23].id
= V4L2_CID_MPEG_VIDEO_HEADER_MODE
;
553 ext_ctrl
[23].value
= V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE
;
554 ext_ctrl
[24].id
= V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT
;
555 ext_ctrl
[24].value
= 1;
557 /* Initial parameters : Frame Skip */
558 switch (pInitParam
->FrameSkip
) {
559 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT
:
560 ext_ctrl
[25].id
= V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
;
561 ext_ctrl
[25].value
= V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT
;
563 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT
:
564 ext_ctrl
[25].id
= V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
;
565 ext_ctrl
[25].value
= V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT
;
568 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
569 ext_ctrl
[25].id
= V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
;
570 ext_ctrl
[25].value
= V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED
;
574 ext_ctrls
.count
= MPEG4_CTRL_NUM
;
578 case VIDEO_CODING_H263
:
580 ExynosVideoEncH263Param
*pH263Param
= &pEncParam
->codecParam
.h263
;
582 /* common parameters but id is depends on codec */
583 ext_ctrl
[8].id
= V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP
;
584 ext_ctrl
[8].value
= pCommonParam
->FrameQp
;
585 ext_ctrl
[9].id
= V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP
;
586 ext_ctrl
[9].value
= pCommonParam
->FrameQp_P
;
587 ext_ctrl
[10].id
= V4L2_CID_MPEG_VIDEO_H263_MAX_QP
;
588 ext_ctrl
[10].value
= pCommonParam
->QSCodeMax
;
589 ext_ctrl
[11].id
= V4L2_CID_MPEG_VIDEO_H263_MIN_QP
;
590 ext_ctrl
[11].value
= pCommonParam
->QSCodeMin
;
591 ext_ctrl
[12].id
= V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF
;
592 ext_ctrl
[12].value
= pCommonParam
->CBRPeriodRf
;
594 /* H263 specific parameters */
595 ext_ctrl
[13].id
= V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE
;
596 ext_ctrl
[13].value
= pH263Param
->FrameRate
;
597 ext_ctrl
[14].id
= V4L2_CID_MPEG_VIDEO_VBV_SIZE
;
598 ext_ctrl
[14].value
= 0;
599 ext_ctrl
[15].id
= V4L2_CID_MPEG_VIDEO_HEADER_MODE
;
600 ext_ctrl
[15].value
= V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE
;
601 ext_ctrl
[16].id
= V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT
;
602 ext_ctrl
[16].value
= 1;
604 /* Initial parameters : Frame Skip */
605 switch (pInitParam
->FrameSkip
) {
606 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT
:
607 ext_ctrl
[17].id
= V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
;
608 ext_ctrl
[17].value
= V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT
;
610 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT
:
611 ext_ctrl
[17].id
= V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
;
612 ext_ctrl
[17].value
= V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT
;
615 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
616 ext_ctrl
[17].id
= V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
;
617 ext_ctrl
[17].value
= V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED
;
621 ext_ctrls
.count
= H263_CTRL_NUM
;
626 ALOGE("[%s] Undefined codec type",__func__
);
627 ret
= VIDEO_ERROR_BADPARAM
;
631 ext_ctrls
.ctrl_class
= V4L2_CTRL_CLASS_MPEG
;
632 ext_ctrls
.controls
= ext_ctrl
;
634 if (exynos_v4l2_s_ext_ctrl(pCtx
->hEnc
, &ext_ctrls
) != 0) {
635 ALOGE("%s: Failed to s_ext_ctrl", __func__
);
636 ret
= VIDEO_ERROR_APIFAIL
;
645 * [Encoder OPS] Set Frame Tag
647 static ExynosVideoErrorType
MFC_Encoder_Set_FrameTag(
651 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
652 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
655 ALOGE("%s: Video context info must be supplied", __func__
);
656 ret
= VIDEO_ERROR_BADPARAM
;
660 if (exynos_v4l2_s_ctrl(pCtx
->hEnc
, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
, frameTag
) != 0) {
661 ALOGE("%s: Failed to s_ctrl", __func__
);
662 ret
= VIDEO_ERROR_APIFAIL
;
671 * [Encoder OPS] Get Frame Tag
673 static int MFC_Encoder_Get_FrameTag(void *pHandle
)
675 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
676 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
681 ALOGE("%s: Video context info must be supplied", __func__
);
685 if (exynos_v4l2_g_ctrl(pCtx
->hEnc
, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
, &frameTag
) != 0) {
686 ALOGE("%s: Failed to g_ctrl", __func__
);
687 ret
= VIDEO_ERROR_APIFAIL
;
696 * [Encoder OPS] Set Frame Type
698 static ExynosVideoErrorType
MFC_Encoder_Set_FrameType(
700 ExynosVideoFrameType frameType
)
702 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
703 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
706 ALOGE("%s: Video context info must be supplied", __func__
);
707 ret
= VIDEO_ERROR_BADPARAM
;
711 if (exynos_v4l2_s_ctrl(pCtx
->hEnc
, V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE
, frameType
) != 0) {
712 ALOGE("%s: Failed to s_ctrl", __func__
);
713 ret
= VIDEO_ERROR_APIFAIL
;
722 * [Encoder OPS] Set Frame Rate
724 static ExynosVideoErrorType
MFC_Encoder_Set_FrameRate(
728 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
729 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
732 ALOGE("%s: Video context info must be supplied", __func__
);
733 ret
= VIDEO_ERROR_BADPARAM
;
737 if (exynos_v4l2_s_ctrl(pCtx
->hEnc
, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH
, frameRate
) != 0) {
738 ALOGE("%s: Failed to s_ctrl", __func__
);
739 ret
= VIDEO_ERROR_APIFAIL
;
748 * [Encoder OPS] Set Bit Rate
750 static ExynosVideoErrorType
MFC_Encoder_Set_BitRate(
754 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
755 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
758 ALOGE("%s: Video context info must be supplied", __func__
);
759 ret
= VIDEO_ERROR_BADPARAM
;
763 if (exynos_v4l2_s_ctrl(pCtx
->hEnc
, V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH
, bitRate
) != 0) {
764 ALOGE("%s: Failed to s_ctrl", __func__
);
765 ret
= VIDEO_ERROR_APIFAIL
;
774 * [Encoder OPS] Set Frame Skip
776 static ExynosVideoErrorType
MFC_Encoder_Set_FrameSkip(
780 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
781 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
784 ALOGE("%s: Video context info must be supplied", __func__
);
785 ret
= VIDEO_ERROR_BADPARAM
;
789 if (exynos_v4l2_s_ctrl(pCtx
->hEnc
, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE
, frameSkip
) != 0) {
790 ALOGE("%s: Failed to s_ctrl", __func__
);
791 ret
= VIDEO_ERROR_APIFAIL
;
800 * [Encoder OPS] Set IDR Period
802 static ExynosVideoErrorType
MFC_Encoder_Set_IDRPeriod(
806 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
807 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
810 ALOGE("%s: Video context info must be supplied", __func__
);
811 ret
= VIDEO_ERROR_BADPARAM
;
815 if (exynos_v4l2_s_ctrl(pCtx
->hEnc
, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD
, IDRPeriod
) != 0) {
816 ALOGE("%s: Failed to s_ctrl", __func__
);
817 ret
= VIDEO_ERROR_APIFAIL
;
826 * [Encoder Buffer OPS] Enable Cacheable (Input)
828 static ExynosVideoErrorType
MFC_Encoder_Enable_Cacheable_Inbuf(void *pHandle
)
830 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
831 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
834 ALOGE("%s: Video context info must be supplied", __func__
);
835 ret
= VIDEO_ERROR_BADPARAM
;
839 if (exynos_v4l2_s_ctrl(pCtx
->hEnc
, V4L2_CID_CACHEABLE
, 2) != 0) {
840 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__
);
841 ret
= VIDEO_ERROR_APIFAIL
;
850 * [Encoder Buffer OPS] Enable Cacheable (Output)
852 static ExynosVideoErrorType
MFC_Encoder_Enable_Cacheable_Outbuf(void *pHandle
)
854 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
855 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
858 ALOGE("%s: Video context info must be supplied", __func__
);
859 ret
= VIDEO_ERROR_BADPARAM
;
863 if (exynos_v4l2_s_ctrl(pCtx
->hEnc
, V4L2_CID_CACHEABLE
, 1) != 0) {
864 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__
);
865 ret
= VIDEO_ERROR_APIFAIL
;
874 * [Encoder Buffer OPS] Set Shareable Buffer (Input)
876 static ExynosVideoErrorType
MFC_Encoder_Set_Shareable_Inbuf(void *pHandle
)
878 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
879 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
882 ALOGE("%s: Video context info must be supplied", __func__
);
883 ret
= VIDEO_ERROR_BADPARAM
;
887 pCtx
->bShareInbuf
= VIDEO_TRUE
;
894 * [Encoder Buffer OPS] Set Shareable Buffer (Output)
896 static ExynosVideoErrorType
MFC_Encoder_Set_Shareable_Outbuf(void *pHandle
)
898 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
899 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
902 ALOGE("%s: Video context info must be supplied", __func__
);
903 ret
= VIDEO_ERROR_BADPARAM
;
907 pCtx
->bShareOutbuf
= VIDEO_TRUE
;
914 * [Encoder Buffer OPS] Get Buffer (Input)
916 static ExynosVideoErrorType
MFC_Encoder_Get_Buffer_Inbuf(
919 ExynosVideoBuffer
**pBuffer
)
921 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
922 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
925 ALOGE("%s: Video context info must be supplied", __func__
);
927 ret
= VIDEO_ERROR_NOBUFFERS
;
931 if (pCtx
->nInbufs
<= nIndex
) {
933 ret
= VIDEO_ERROR_BADPARAM
;
937 *pBuffer
= (ExynosVideoBuffer
*)&pCtx
->pInbuf
[nIndex
];
944 * [Encoder Buffer OPS] Get Buffer (Output)
946 static ExynosVideoErrorType
MFC_Encoder_Get_Buffer_Outbuf(
949 ExynosVideoBuffer
**pBuffer
)
951 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
952 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
955 ALOGE("%s: Video context info must be supplied", __func__
);
957 ret
= VIDEO_ERROR_NOBUFFERS
;
961 if (pCtx
->nOutbufs
<= nIndex
) {
963 ret
= VIDEO_ERROR_BADPARAM
;
967 *pBuffer
= (ExynosVideoBuffer
*)&pCtx
->pOutbuf
[nIndex
];
974 * [Encoder Buffer OPS] Set Geometry (Src)
976 static ExynosVideoErrorType
MFC_Encoder_Set_Geometry_Inbuf(
978 ExynosVideoGeometry
*bufferConf
)
980 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
981 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
983 struct v4l2_format fmt
;
986 ALOGE("%s: Video context info must be supplied", __func__
);
987 ret
= VIDEO_ERROR_BADPARAM
;
991 if (bufferConf
== NULL
) {
992 ALOGE("%s: Buffer geometry must be supplied", __func__
);
993 ret
= VIDEO_ERROR_BADPARAM
;
997 memset(&fmt
, 0, sizeof(fmt
));
999 fmt
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1000 fmt
.fmt
.pix_mp
.pixelformat
= __ColorFormatType_To_V4L2PixelFormat(bufferConf
->eColorFormat
);
1001 fmt
.fmt
.pix_mp
.width
= bufferConf
->nFrameWidth
;
1002 fmt
.fmt
.pix_mp
.height
= bufferConf
->nFrameHeight
;
1003 fmt
.fmt
.pix_mp
.num_planes
= VIDEO_ENCODER_INBUF_PLANES
;
1005 if (exynos_v4l2_s_fmt(pCtx
->hEnc
, &fmt
) != 0) {
1006 ALOGE("%s: Failed to s_fmt", __func__
);
1007 ret
= VIDEO_ERROR_APIFAIL
;
1011 memcpy(&pCtx
->inbufGeometry
, bufferConf
, sizeof(pCtx
->inbufGeometry
));
1018 * [Encoder Buffer OPS] Get Geometry (Src)
1020 static ExynosVideoErrorType
MFC_Encoder_Get_Geometry_Inbuf(
1022 ExynosVideoGeometry
*bufferConf
)
1024 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1025 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1027 struct v4l2_format fmt
;
1030 ALOGE("%s: Video context info must be supplied", __func__
);
1031 ret
= VIDEO_ERROR_BADPARAM
;
1035 if (bufferConf
== NULL
) {
1036 ALOGE("%s: Buffer geometry must be supplied", __func__
);
1037 ret
= VIDEO_ERROR_BADPARAM
;
1041 memset(&fmt
, 0, sizeof(fmt
));
1043 fmt
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1044 if (exynos_v4l2_g_fmt(pCtx
->hEnc
, &fmt
) != 0) {
1045 ALOGE("%s: Failed to g_fmt", __func__
);
1046 ret
= VIDEO_ERROR_APIFAIL
;
1050 bufferConf
->nFrameHeight
= fmt
.fmt
.pix_mp
.width
;
1051 bufferConf
->nFrameHeight
= fmt
.fmt
.pix_mp
.height
;
1052 bufferConf
->nSizeImage
= fmt
.fmt
.pix_mp
.plane_fmt
[0].sizeimage
;
1059 * [Encoder Buffer OPS] Set Geometry (Dst)
1061 static ExynosVideoErrorType
MFC_Encoder_Set_Geometry_Outbuf(
1063 ExynosVideoGeometry
*bufferConf
)
1065 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1066 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1068 struct v4l2_format fmt
;
1071 ALOGE("%s: Video context info must be supplied", __func__
);
1072 ret
= VIDEO_ERROR_BADPARAM
;
1076 if (bufferConf
== NULL
) {
1077 ALOGE("%s: Buffer geometry must be supplied", __func__
);
1078 ret
= VIDEO_ERROR_BADPARAM
;
1082 memset(&fmt
, 0, sizeof(fmt
));
1084 fmt
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1085 fmt
.fmt
.pix_mp
.pixelformat
= __CodingType_To_V4L2PixelFormat(bufferConf
->eCompressionFormat
);
1086 fmt
.fmt
.pix_mp
.plane_fmt
[0].sizeimage
= bufferConf
->nSizeImage
;
1088 if (exynos_v4l2_s_fmt(pCtx
->hEnc
, &fmt
) != 0) {
1089 ALOGE("%s: Failed to s_fmt", __func__
);
1090 ret
= VIDEO_ERROR_APIFAIL
;
1094 memcpy(&pCtx
->outbufGeometry
, bufferConf
, sizeof(pCtx
->outbufGeometry
));
1101 * [Encoder Buffer OPS] Get Geometry (Dst)
1103 static ExynosVideoErrorType
MFC_Encoder_Get_Geometry_Outbuf(
1105 ExynosVideoGeometry
*bufferConf
)
1107 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1108 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1110 struct v4l2_format fmt
;
1113 ALOGE("%s: Video context info must be supplied", __func__
);
1114 ret
= VIDEO_ERROR_BADPARAM
;
1118 if (bufferConf
== NULL
) {
1119 ALOGE("%s: Buffer geometry must be supplied", __func__
);
1120 ret
= VIDEO_ERROR_BADPARAM
;
1124 memset(&fmt
, 0, sizeof(fmt
));
1126 fmt
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1127 if (exynos_v4l2_g_fmt(pCtx
->hEnc
, &fmt
) != 0) {
1128 ALOGE("%s: Failed to g_fmt", __func__
);
1129 ret
= VIDEO_ERROR_APIFAIL
;
1133 bufferConf
->nSizeImage
= fmt
.fmt
.pix_mp
.plane_fmt
[0].sizeimage
;
1140 * [Encoder Buffer OPS] Setup (Src)
1142 static ExynosVideoErrorType
MFC_Encoder_Setup_Inbuf(
1144 unsigned int nBufferCount
)
1146 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1147 ExynosVideoPlane
*pVideoPlane
= NULL
;
1148 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1150 struct v4l2_requestbuffers req
;
1151 struct v4l2_buffer buf
;
1152 struct v4l2_plane planes
[VIDEO_ENCODER_INBUF_PLANES
];
1156 ALOGE("%s: Video context info must be supplied", __func__
);
1157 ret
= VIDEO_ERROR_BADPARAM
;
1161 if (nBufferCount
== 0) {
1162 ALOGE("%s: Buffer count must be greater than 0", __func__
);
1163 ret
= VIDEO_ERROR_BADPARAM
;
1167 memset(&req
, 0, sizeof(req
));
1169 req
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1170 req
.count
= nBufferCount
;
1172 if (pCtx
->bShareInbuf
== VIDEO_TRUE
)
1173 req
.memory
= pCtx
->nMemoryType
;
1175 req
.memory
= V4L2_MEMORY_MMAP
;
1177 if (exynos_v4l2_reqbufs(pCtx
->hEnc
, &req
) != 0) {
1178 ALOGE("Failed to require buffer");
1179 ret
= VIDEO_ERROR_APIFAIL
;
1183 pCtx
->nInbufs
= (int)req
.count
;
1185 pCtx
->pInbuf
= malloc(sizeof(*pCtx
->pInbuf
) * pCtx
->nInbufs
);
1186 if (pCtx
->pInbuf
== NULL
) {
1187 ALOGE("%s: Failed to allocate input buffer context", __func__
);
1188 ret
= VIDEO_ERROR_NOMEM
;
1191 memset(pCtx
->pInbuf
, 0, sizeof(*pCtx
->pInbuf
) * pCtx
->nInbufs
);
1193 memset(&buf
, 0, sizeof(buf
));
1195 if (pCtx
->bShareInbuf
== VIDEO_FALSE
) {
1196 buf
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1197 buf
.memory
= V4L2_MEMORY_MMAP
;
1198 buf
.m
.planes
= planes
;
1199 buf
.length
= VIDEO_ENCODER_INBUF_PLANES
;
1201 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
1203 if (exynos_v4l2_querybuf(pCtx
->hEnc
, &buf
) != 0) {
1204 ALOGE("%s: Failed to querybuf", __func__
);
1205 ret
= VIDEO_ERROR_APIFAIL
;
1209 for (j
= 0; j
< VIDEO_ENCODER_INBUF_PLANES
; j
++) {
1210 pVideoPlane
= &pCtx
->pInbuf
[i
].planes
[j
];
1211 pVideoPlane
->addr
= mmap(NULL
,
1212 buf
.m
.planes
[j
].length
, PROT_READ
| PROT_WRITE
,
1213 MAP_SHARED
, pCtx
->hEnc
, buf
.m
.planes
[j
].m
.mem_offset
);
1215 if (pVideoPlane
->addr
== MAP_FAILED
) {
1216 ALOGE("%s: Failed to map", __func__
);
1217 ret
= VIDEO_ERROR_MAPFAIL
;
1221 pVideoPlane
->allocSize
= buf
.m
.planes
[j
].length
;
1222 pVideoPlane
->dataSize
= 0;
1225 pCtx
->pInbuf
[i
].pGeometry
= &pCtx
->inbufGeometry
;
1226 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
1227 pCtx
->pInbuf
[i
].bRegistered
= VIDEO_TRUE
;
1231 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
1232 pCtx
->pInbuf
[i
].pGeometry
= &pCtx
->inbufGeometry
;
1233 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
1234 pCtx
->pInbuf
[i
].bRegistered
= VIDEO_FALSE
;
1241 if ((pCtx
!= NULL
) && (pCtx
->pInbuf
!= NULL
)) {
1242 if (pCtx
->bShareInbuf
== VIDEO_FALSE
) {
1243 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
1244 for (j
= 0; j
< VIDEO_ENCODER_INBUF_PLANES
; j
++) {
1245 pVideoPlane
= &pCtx
->pInbuf
[i
].planes
[j
];
1246 if (pVideoPlane
->addr
== MAP_FAILED
) {
1247 pVideoPlane
->addr
= NULL
;
1251 munmap(pVideoPlane
->addr
, pVideoPlane
->allocSize
);
1263 * [Encoder Buffer OPS] Setup (Dst)
1265 static ExynosVideoErrorType
MFC_Encoder_Setup_Outbuf(
1267 unsigned int nBufferCount
)
1269 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1270 ExynosVideoPlane
*pVideoPlane
= NULL
;
1271 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1273 struct v4l2_requestbuffers req
;
1274 struct v4l2_buffer buf
;
1275 struct v4l2_plane planes
[VIDEO_ENCODER_OUTBUF_PLANES
];
1279 ALOGE("%s: Video context info must be supplied", __func__
);
1280 ret
= VIDEO_ERROR_BADPARAM
;
1284 if (nBufferCount
== 0) {
1285 ALOGE("%s: Buffer count must be greater than 0", __func__
);
1286 ret
= VIDEO_ERROR_BADPARAM
;
1290 memset(&req
, 0, sizeof(req
));
1292 req
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1293 req
.count
= nBufferCount
;
1295 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
)
1296 req
.memory
= pCtx
->nMemoryType
;
1298 req
.memory
= V4L2_MEMORY_MMAP
;
1300 if (exynos_v4l2_reqbufs(pCtx
->hEnc
, &req
) != 0) {
1301 ALOGE("%s: Failed to reqbuf", __func__
);
1302 ret
= VIDEO_ERROR_APIFAIL
;
1306 pCtx
->nOutbufs
= req
.count
;
1308 pCtx
->pOutbuf
= malloc(sizeof(*pCtx
->pOutbuf
) * pCtx
->nOutbufs
);
1309 if (pCtx
->pOutbuf
== NULL
) {
1310 ALOGE("%s: Failed to allocate output buffer context", __func__
);
1311 ret
= VIDEO_ERROR_NOMEM
;
1314 memset(pCtx
->pOutbuf
, 0, sizeof(*pCtx
->pOutbuf
) * pCtx
->nOutbufs
);
1316 memset(&buf
, 0, sizeof(buf
));
1318 if (pCtx
->bShareOutbuf
== VIDEO_FALSE
) {
1319 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1320 buf
.memory
= V4L2_MEMORY_MMAP
;
1321 buf
.m
.planes
= planes
;
1322 buf
.length
= VIDEO_ENCODER_OUTBUF_PLANES
;
1324 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
1326 if (exynos_v4l2_querybuf(pCtx
->hEnc
, &buf
) != 0) {
1327 ALOGE("%s: Failed to querybuf", __func__
);
1328 ret
= VIDEO_ERROR_APIFAIL
;
1332 for (j
= 0; j
< VIDEO_ENCODER_OUTBUF_PLANES
; j
++) {
1333 pVideoPlane
= &pCtx
->pOutbuf
[i
].planes
[j
];
1334 pVideoPlane
->addr
= mmap(NULL
,
1335 buf
.m
.planes
[j
].length
, PROT_READ
| PROT_WRITE
,
1336 MAP_SHARED
, pCtx
->hEnc
, buf
.m
.planes
[j
].m
.mem_offset
);
1338 if (pVideoPlane
->addr
== MAP_FAILED
) {
1339 ALOGE("%s: Failed to map", __func__
);
1340 ret
= VIDEO_ERROR_MAPFAIL
;
1344 pVideoPlane
->allocSize
= buf
.m
.planes
[j
].length
;
1345 pVideoPlane
->dataSize
= 0;
1348 pCtx
->pOutbuf
[i
].pGeometry
= &pCtx
->outbufGeometry
;
1349 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
1350 pCtx
->pOutbuf
[i
].bRegistered
= VIDEO_TRUE
;
1353 for (i
= 0; i
< pCtx
->nOutbufs
; i
++ ) {
1354 pCtx
->pOutbuf
[i
].pGeometry
= &pCtx
->outbufGeometry
;
1355 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
1356 pCtx
->pOutbuf
[i
].bRegistered
= VIDEO_FALSE
;
1363 if ((pCtx
!= NULL
) && (pCtx
->pOutbuf
!= NULL
)) {
1364 if (pCtx
->bShareOutbuf
== VIDEO_FALSE
) {
1365 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
1366 for (j
= 0; j
< VIDEO_ENCODER_OUTBUF_PLANES
; j
++) {
1367 pVideoPlane
= &pCtx
->pOutbuf
[i
].planes
[j
];
1368 if (pVideoPlane
->addr
== MAP_FAILED
) {
1369 pVideoPlane
->addr
= NULL
;
1373 munmap(pVideoPlane
->addr
, pVideoPlane
->allocSize
);
1378 free(pCtx
->pOutbuf
);
1385 * [Encoder Buffer OPS] Run (src)
1387 static ExynosVideoErrorType
MFC_Encoder_Run_Inbuf(void *pHandle
)
1389 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1390 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1393 ALOGE("%s: Video context info must be supplied", __func__
);
1394 ret
= VIDEO_ERROR_BADPARAM
;
1398 if (pCtx
->bStreamonInbuf
== VIDEO_FALSE
) {
1399 if (exynos_v4l2_streamon(pCtx
->hEnc
, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) != 0) {
1400 ALOGE("%s: Failed to streamon for input buffer", __func__
);
1401 ret
= VIDEO_ERROR_APIFAIL
;
1404 pCtx
->bStreamonInbuf
= VIDEO_TRUE
;
1412 * [Encoder Buffer OPS] Run (Dst)
1414 static ExynosVideoErrorType
MFC_Encoder_Run_Outbuf(void *pHandle
)
1416 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1417 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1420 ALOGE("%s: Video context info must be supplied", __func__
);
1421 ret
= VIDEO_ERROR_BADPARAM
;
1425 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
1426 if (exynos_v4l2_streamon(pCtx
->hEnc
, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) != 0) {
1427 ALOGE("%s: Failed to streamon for output buffer", __func__
);
1428 ret
= VIDEO_ERROR_APIFAIL
;
1431 pCtx
->bStreamonOutbuf
= VIDEO_TRUE
;
1439 * [Encoder Buffer OPS] Stop (Src)
1441 static ExynosVideoErrorType
MFC_Encoder_Stop_Inbuf(void *pHandle
)
1443 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1444 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1448 ALOGE("%s: Video context info must be supplied", __func__
);
1449 ret
= VIDEO_ERROR_BADPARAM
;
1453 if (pCtx
->bStreamonInbuf
== VIDEO_TRUE
) {
1454 if (exynos_v4l2_streamoff(pCtx
->hEnc
, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) != 0) {
1455 ALOGE("%s: Failed to streamoff for input buffer", __func__
);
1456 ret
= VIDEO_ERROR_APIFAIL
;
1459 pCtx
->bStreamonInbuf
= VIDEO_FALSE
;
1462 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
1463 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
1471 * [Encoder Buffer OPS] Stop (Dst)
1473 static ExynosVideoErrorType
MFC_Encoder_Stop_Outbuf(void *pHandle
)
1475 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1476 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1480 ALOGE("%s: Video context info must be supplied", __func__
);
1481 ret
= VIDEO_ERROR_BADPARAM
;
1485 if (pCtx
->bStreamonOutbuf
== VIDEO_TRUE
) {
1486 if (exynos_v4l2_streamoff(pCtx
->hEnc
, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) != 0) {
1487 ALOGE("%s: Failed to streamoff for output buffer", __func__
);
1488 ret
= VIDEO_ERROR_APIFAIL
;
1491 pCtx
->bStreamonOutbuf
= VIDEO_FALSE
;
1494 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
1495 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
1503 * [Encoder Buffer OPS] Wait (Src)
1505 static ExynosVideoErrorType
MFC_Encoder_Wait_Inbuf(void *pHandle
)
1507 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1508 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1510 struct pollfd poll_events
;
1514 ALOGE("%s: Video context info must be supplied", __func__
);
1515 ret
= VIDEO_ERROR_BADPARAM
;
1519 poll_events
.fd
= pCtx
->hEnc
;
1520 poll_events
.events
= POLLOUT
| POLLERR
;
1521 poll_events
.revents
= 0;
1524 poll_state
= poll((struct pollfd
*)&poll_events
, 1, VIDEO_ENCODER_POLL_TIMEOUT
);
1525 if (poll_state
> 0) {
1526 if (poll_events
.revents
& POLLOUT
) {
1529 ALOGE("%s: Poll return error", __func__
);
1530 ret
= VIDEO_ERROR_POLL
;
1533 } else if (poll_state
< 0) {
1534 ALOGE("%s: Poll state error", __func__
);
1535 ret
= VIDEO_ERROR_POLL
;
1538 } while (poll_state
== 0);
1545 * [Encoder Buffer OPS] Wait (Dst)
1547 static ExynosVideoErrorType
MFC_Encoder_Wait_Outbuf(void *pHandle
)
1549 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1550 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1552 struct pollfd poll_events
;
1554 int bframe_count
= 0; // FIXME
1557 ALOGE("%s: Video context info must be supplied", __func__
);
1558 ret
= VIDEO_ERROR_BADPARAM
;
1562 poll_events
.fd
= pCtx
->hEnc
;
1563 poll_events
.events
= POLLIN
| POLLERR
;
1564 poll_events
.revents
= 0;
1567 poll_state
= poll((struct pollfd
*)&poll_events
, 1, VIDEO_ENCODER_POLL_TIMEOUT
);
1568 if (poll_state
> 0) {
1569 if (poll_events
.revents
& POLLIN
) {
1572 ALOGE("%s: Poll return error", __func__
);
1573 ret
= VIDEO_ERROR_POLL
;
1576 } else if (poll_state
< 0) {
1577 ALOGE("%s: Poll state error", __func__
);
1578 ret
= VIDEO_ERROR_POLL
;
1581 bframe_count
++; // FIXME
1583 } while (poll_state
== 0 && bframe_count
< 5); // FIXME
1589 static ExynosVideoErrorType
MFC_Encoder_Register_Inbuf(
1591 ExynosVideoPlane
*planes
,
1594 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1595 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1598 if ((pCtx
== NULL
) || (planes
== NULL
) || (nPlanes
!= VIDEO_ENCODER_INBUF_PLANES
)) {
1599 ALOGE("%s: input params must be supplied", __func__
);
1600 ret
= VIDEO_ERROR_BADPARAM
;
1604 for (nIndex
= 0; nIndex
< pCtx
->nInbufs
; nIndex
++) {
1605 if (pCtx
->pInbuf
[nIndex
].bRegistered
== VIDEO_FALSE
) {
1607 for (plane
= 0; plane
< nPlanes
; plane
++) {
1608 pCtx
->pInbuf
[nIndex
].planes
[plane
].addr
= planes
[plane
].addr
;
1609 pCtx
->pInbuf
[nIndex
].planes
[plane
].allocSize
= planes
[plane
].allocSize
;
1610 pCtx
->pInbuf
[nIndex
].planes
[plane
].fd
= planes
[plane
].fd
;
1612 pCtx
->pInbuf
[nIndex
].bRegistered
= VIDEO_TRUE
;
1617 if (nIndex
== pCtx
->nInbufs
) {
1618 ALOGE("%s: can not find non-registered input buffer", __func__
);
1619 ret
= VIDEO_ERROR_NOBUFFERS
;
1626 static ExynosVideoErrorType
MFC_Encoder_Register_Outbuf(
1628 ExynosVideoPlane
*planes
,
1631 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1632 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1635 if ((pCtx
== NULL
) || (planes
== NULL
) || (nPlanes
!= VIDEO_ENCODER_OUTBUF_PLANES
)) {
1636 ALOGE("%s: params must be supplied", __func__
);
1637 ret
= VIDEO_ERROR_BADPARAM
;
1641 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1642 if (pCtx
->pOutbuf
[nIndex
].bRegistered
== VIDEO_FALSE
) {
1644 for (plane
= 0; plane
< nPlanes
; plane
++) {
1645 pCtx
->pOutbuf
[nIndex
].planes
[plane
].addr
= planes
[plane
].addr
;
1646 pCtx
->pOutbuf
[nIndex
].planes
[plane
].allocSize
= planes
[plane
].allocSize
;
1647 pCtx
->pOutbuf
[nIndex
].planes
[plane
].fd
= planes
[plane
].fd
;
1649 pCtx
->pOutbuf
[nIndex
].bRegistered
= VIDEO_TRUE
;
1654 if (nIndex
== pCtx
->nOutbufs
) {
1655 ALOGE("%s: can not find non-registered output buffer", __func__
);
1656 ret
= VIDEO_ERROR_NOBUFFERS
;
1663 static ExynosVideoErrorType
MFC_Encoder_Clear_RegisteredBuffer_Inbuf(void *pHandle
)
1665 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1666 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1670 ALOGE("%s: Video context info must be supplied", __func__
);
1671 ret
= VIDEO_ERROR_BADPARAM
;
1675 for (nIndex
= 0; nIndex
< pCtx
->nInbufs
; nIndex
++) {
1676 pCtx
->pInbuf
[nIndex
].planes
[0].addr
= NULL
;
1677 pCtx
->pInbuf
[nIndex
].bRegistered
= VIDEO_FALSE
;
1684 static ExynosVideoErrorType
MFC_Encoder_Clear_RegisteredBuffer_Outbuf(void *pHandle
)
1686 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1687 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1691 ALOGE("%s: Video context info must be supplied", __func__
);
1692 ret
= VIDEO_ERROR_BADPARAM
;
1696 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1697 pCtx
->pOutbuf
[nIndex
].planes
[0].addr
= NULL
;
1698 pCtx
->pOutbuf
[nIndex
].bRegistered
= VIDEO_FALSE
;
1706 * [Encoder Buffer OPS] Find (Input)
1708 static int MFC_Encoder_Find_Inbuf(
1710 unsigned char *pBuffer
)
1712 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1716 ALOGE("%s: Video context info must be supplied", __func__
);
1720 for (nIndex
= 0; nIndex
< pCtx
->nInbufs
; nIndex
++) {
1721 if (pCtx
->pInbuf
[nIndex
].bQueued
== VIDEO_FALSE
) {
1722 if ((pBuffer
== NULL
) ||
1723 (pCtx
->pInbuf
[nIndex
].planes
[0].addr
== pBuffer
))
1728 if (nIndex
== pCtx
->nInbufs
)
1736 * [Encoder Buffer OPS] Find (Outnput)
1738 static int MFC_Encoder_Find_Outbuf(
1740 unsigned char *pBuffer
)
1742 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1746 ALOGE("%s: Video context info must be supplied", __func__
);
1750 for (nIndex
= 0; nIndex
< pCtx
->nOutbufs
; nIndex
++) {
1751 if (pCtx
->pOutbuf
[nIndex
].bQueued
== VIDEO_FALSE
) {
1752 if ((pBuffer
== NULL
) ||
1753 (pCtx
->pOutbuf
[nIndex
].planes
[0].addr
== pBuffer
))
1758 if (nIndex
== pCtx
->nOutbufs
)
1766 * [Encoder Buffer OPS] Enqueue (Input)
1768 static ExynosVideoErrorType
MFC_Encoder_Enqueue_Inbuf(
1770 unsigned char *pBuffer
[],
1771 unsigned int dataSize
[],
1775 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1776 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1777 pthread_mutex_t
*pMutex
= NULL
;
1779 struct v4l2_plane planes
[VIDEO_ENCODER_INBUF_PLANES
];
1780 struct v4l2_buffer buf
;
1784 ALOGE("%s: Video context info must be supplied", __func__
);
1785 ret
= VIDEO_ERROR_BADPARAM
;
1789 if (VIDEO_ENCODER_INBUF_PLANES
< nPlanes
) {
1790 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__
,
1791 VIDEO_ENCODER_INBUF_PLANES
, nPlanes
);
1792 ret
= VIDEO_ERROR_BADPARAM
;
1796 memset(&buf
, 0, sizeof(buf
));
1798 buf
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1799 buf
.m
.planes
= planes
;
1800 buf
.length
= VIDEO_ENCODER_INBUF_PLANES
;
1802 pMutex
= (pthread_mutex_t
*)pCtx
->pInMutex
;
1803 pthread_mutex_lock(pMutex
);
1804 index
= MFC_Encoder_Find_Inbuf(pCtx
, pBuffer
[0]);
1806 pthread_mutex_unlock(pMutex
);
1807 ALOGE("%s: Failed to get index", __func__
);
1808 ret
= VIDEO_ERROR_NOBUFFERS
;
1813 pCtx
->pInbuf
[buf
.index
].bQueued
= VIDEO_TRUE
;
1814 pthread_mutex_unlock(pMutex
);
1816 if (pCtx
->bShareInbuf
== VIDEO_TRUE
) {
1817 buf
.memory
= pCtx
->nMemoryType
;
1818 for (i
= 0; i
< nPlanes
; i
++) {
1819 /* V4L2_MEMORY_USERPTR */
1820 buf
.m
.planes
[i
].m
.userptr
= (unsigned long)pBuffer
[i
];
1821 /* V4L2_MEMORY_DMABUF */
1822 buf
.m
.planes
[i
].m
.fd
= pCtx
->pInbuf
[buf
.index
].planes
[i
].fd
;
1823 buf
.m
.planes
[i
].length
= pCtx
->pInbuf
[index
].planes
[i
].allocSize
;
1824 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1827 buf
.memory
= V4L2_MEMORY_MMAP
;
1828 for (i
= 0; i
< nPlanes
; i
++)
1829 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1832 if (exynos_v4l2_qbuf(pCtx
->hEnc
, &buf
) != 0) {
1833 ALOGE("%s: Failed to enqueue input buffer", __func__
);
1834 pCtx
->pInbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1835 ret
= VIDEO_ERROR_APIFAIL
;
1839 pCtx
->pInbuf
[buf
.index
].pPrivate
= pPrivate
;
1846 * [Encoder Buffer OPS] Enqueue (Output)
1848 static ExynosVideoErrorType
MFC_Encoder_Enqueue_Outbuf(
1850 unsigned char *pBuffer
[],
1851 unsigned int dataSize
[],
1855 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1856 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1857 pthread_mutex_t
*pMutex
= NULL
;
1859 struct v4l2_plane planes
[VIDEO_ENCODER_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_ENCODER_OUTBUF_PLANES
< nPlanes
) {
1870 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__
,
1871 VIDEO_ENCODER_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_ENCODER_OUTBUF_PLANES
;
1881 pMutex
= (pthread_mutex_t
*)pCtx
->pOutMutex
;
1882 pthread_mutex_lock(pMutex
);
1883 index
= MFC_Encoder_Find_Outbuf(pCtx
, pBuffer
[0]);
1885 pthread_mutex_unlock(pMutex
);
1886 ALOGE("%s: Failed to get index", __func__
);
1887 ret
= VIDEO_ERROR_NOBUFFERS
;
1891 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_TRUE
;
1892 pthread_mutex_unlock(pMutex
);
1894 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
) {
1895 buf
.memory
= pCtx
->nMemoryType
;
1896 for (i
= 0; i
< nPlanes
; i
++) {
1897 /* V4L2_MEMORY_USERPTR */
1898 buf
.m
.planes
[i
].m
.userptr
= (unsigned long)pBuffer
[i
];
1899 /* V4L2_MEMORY_DMABUF */
1900 buf
.m
.planes
[i
].m
.fd
= pCtx
->pOutbuf
[index
].planes
[i
].fd
;
1901 buf
.m
.planes
[i
].length
= pCtx
->pOutbuf
[index
].planes
[i
].allocSize
;
1902 buf
.m
.planes
[i
].bytesused
= dataSize
[i
];
1905 buf
.memory
= V4L2_MEMORY_MMAP
;
1908 if (exynos_v4l2_qbuf(pCtx
->hEnc
, &buf
) != 0) {
1909 ALOGE("%s: Failed to enqueue output buffer", __func__
);
1910 pCtx
->pOutbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1911 ret
= VIDEO_ERROR_APIFAIL
;
1915 pCtx
->pOutbuf
[buf
.index
].pPrivate
= pPrivate
;
1922 * [Encoder Buffer OPS] Enqueue All (Output)
1924 static ExynosVideoErrorType
MFC_Encoder_Enqueue_All_Outbuf(void *pHandle
)
1926 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1927 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
1929 unsigned char *pBuffer
[VIDEO_BUFFER_MAX_PLANES
] = {NULL
, };
1930 unsigned int dataSize
[VIDEO_BUFFER_MAX_PLANES
] = {0, };
1935 ALOGE("%s: Video context info must be supplied", __func__
);
1936 ret
= VIDEO_ERROR_BADPARAM
;
1940 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
1941 ret
= MFC_Encoder_Enqueue_Outbuf(pCtx
, pBuffer
, dataSize
, 1, NULL
);
1942 if (ret
!= VIDEO_ERROR_NONE
)
1951 * [Encoder Buffer OPS] Dequeue (Input)
1953 static ExynosVideoBuffer
*MFC_Encoder_Dequeue_Inbuf(void *pHandle
)
1955 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1956 ExynosVideoBuffer
*pInbuf
= NULL
;
1958 struct v4l2_buffer buf
;
1961 ALOGE("%s: Video context info must be supplied", __func__
);
1965 if (pCtx
->bStreamonInbuf
== VIDEO_FALSE
) {
1970 memset(&buf
, 0, sizeof(buf
));
1972 buf
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1974 if (pCtx
->bShareInbuf
== VIDEO_TRUE
)
1975 buf
.memory
= pCtx
->nMemoryType
;
1977 buf
.memory
= V4L2_MEMORY_MMAP
;
1979 if (exynos_v4l2_dqbuf(pCtx
->hEnc
, &buf
) != 0) {
1984 pInbuf
= &pCtx
->pInbuf
[buf
.index
];
1985 pCtx
->pInbuf
[buf
.index
].bQueued
= VIDEO_FALSE
;
1992 * [Encoder Buffer OPS] Dequeue (Output)
1994 static ExynosVideoBuffer
*MFC_Encoder_Dequeue_Outbuf(void *pHandle
)
1996 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
1997 ExynosVideoBuffer
*pOutbuf
= NULL
;
1999 struct v4l2_buffer buf
;
2000 struct v4l2_plane planes
[VIDEO_ENCODER_OUTBUF_PLANES
];
2004 ALOGE("%s: Video context info must be supplied", __func__
);
2008 if (pCtx
->bStreamonOutbuf
== VIDEO_FALSE
) {
2013 memset(&buf
, 0, sizeof(buf
));
2014 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
2015 buf
.m
.planes
= planes
;
2018 if (pCtx
->bShareOutbuf
== VIDEO_TRUE
)
2019 buf
.memory
= pCtx
->nMemoryType
;
2021 buf
.memory
= V4L2_MEMORY_MMAP
;
2023 /* no error case for output buffer dequeue in encoder */
2024 if (exynos_v4l2_dqbuf(pCtx
->hEnc
, &buf
) != 0) {
2028 pOutbuf
= &pCtx
->pOutbuf
[buf
.index
];
2029 pOutbuf
->planes
[0].dataSize
= buf
.m
.planes
[0].bytesused
;
2031 switch (buf
.flags
& (0x7 << 3)) {
2032 case V4L2_BUF_FLAG_KEYFRAME
:
2033 pOutbuf
->frameType
= VIDEO_FRAME_I
;
2035 case V4L2_BUF_FLAG_PFRAME
:
2036 pOutbuf
->frameType
= VIDEO_FRAME_P
;
2038 case V4L2_BUF_FLAG_BFRAME
:
2039 pOutbuf
->frameType
= VIDEO_FRAME_B
;
2042 ALOGI("%s: encoded frame type is = %d",__func__
, (buf
.flags
& (0x7 << 3)));
2043 pOutbuf
->frameType
= VIDEO_FRAME_OTHERS
;
2047 pOutbuf
->bQueued
= VIDEO_FALSE
;
2053 static ExynosVideoErrorType
MFC_Encoder_Clear_Queued_Inbuf(void *pHandle
)
2055 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
2056 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
2060 ALOGE("%s: Video context info must be supplied", __func__
);
2061 ret
= VIDEO_ERROR_BADPARAM
;
2065 for (i
= 0; i
< pCtx
->nInbufs
; i
++) {
2066 pCtx
->pInbuf
[i
].bQueued
= VIDEO_FALSE
;
2073 static ExynosVideoErrorType
MFC_Encoder_Clear_Queued_Outbuf(void *pHandle
)
2075 ExynosVideoEncContext
*pCtx
= (ExynosVideoEncContext
*)pHandle
;
2076 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
2080 ALOGE("%s: Video context info must be supplied", __func__
);
2081 ret
= VIDEO_ERROR_BADPARAM
;
2085 for (i
= 0; i
< pCtx
->nOutbufs
; i
++) {
2086 pCtx
->pOutbuf
[i
].bQueued
= VIDEO_FALSE
;
2094 * [Encoder OPS] Common
2096 static ExynosVideoEncOps defEncOps
= {
2098 .Init
= MFC_Encoder_Init
,
2099 .Finalize
= MFC_Encoder_Finalize
,
2100 .Set_EncParam
= MFC_Encoder_Set_EncParam
,
2101 .Set_FrameType
= MFC_Encoder_Set_FrameType
,
2102 .Set_FrameRate
= MFC_Encoder_Set_FrameRate
,
2103 .Set_BitRate
= MFC_Encoder_Set_BitRate
,
2104 .Set_FrameSkip
= MFC_Encoder_Set_FrameSkip
,
2105 .Set_IDRPeriod
= MFC_Encoder_Set_IDRPeriod
,
2106 .Set_FrameTag
= MFC_Encoder_Set_FrameTag
,
2107 .Get_FrameTag
= MFC_Encoder_Get_FrameTag
,
2111 * [Encoder Buffer OPS] Input
2113 static ExynosVideoEncBufferOps defInbufOps
= {
2115 .Enable_Cacheable
= MFC_Encoder_Enable_Cacheable_Inbuf
,
2116 .Set_Shareable
= MFC_Encoder_Set_Shareable_Inbuf
,
2118 .Set_Geometry
= MFC_Encoder_Set_Geometry_Inbuf
,
2119 .Get_Geometry
= MFC_Encoder_Get_Geometry_Inbuf
,
2120 .Setup
= MFC_Encoder_Setup_Inbuf
,
2121 .Run
= MFC_Encoder_Run_Inbuf
,
2122 .Stop
= MFC_Encoder_Stop_Inbuf
,
2123 .Enqueue
= MFC_Encoder_Enqueue_Inbuf
,
2124 .Enqueue_All
= NULL
,
2125 .Dequeue
= MFC_Encoder_Dequeue_Inbuf
,
2126 .Register
= MFC_Encoder_Register_Inbuf
,
2127 .Clear_RegisteredBuffer
= MFC_Encoder_Clear_RegisteredBuffer_Inbuf
,
2128 .Clear_Queue
= MFC_Encoder_Clear_Queued_Inbuf
,
2132 * [Encoder Buffer OPS] Output
2134 static ExynosVideoEncBufferOps defOutbufOps
= {
2136 .Enable_Cacheable
= MFC_Encoder_Enable_Cacheable_Outbuf
,
2137 .Set_Shareable
= MFC_Encoder_Set_Shareable_Outbuf
,
2138 .Get_Buffer
= MFC_Encoder_Get_Buffer_Outbuf
,
2139 .Set_Geometry
= MFC_Encoder_Set_Geometry_Outbuf
,
2140 .Get_Geometry
= MFC_Encoder_Get_Geometry_Outbuf
,
2141 .Setup
= MFC_Encoder_Setup_Outbuf
,
2142 .Run
= MFC_Encoder_Run_Outbuf
,
2143 .Stop
= MFC_Encoder_Stop_Outbuf
,
2144 .Enqueue
= MFC_Encoder_Enqueue_Outbuf
,
2145 .Enqueue_All
= NULL
,
2146 .Dequeue
= MFC_Encoder_Dequeue_Outbuf
,
2147 .Register
= MFC_Encoder_Register_Outbuf
,
2148 .Clear_RegisteredBuffer
= MFC_Encoder_Clear_RegisteredBuffer_Outbuf
,
2149 .Clear_Queue
= MFC_Encoder_Clear_Queued_Outbuf
,
2152 int Exynos_Video_Register_Encoder(
2153 ExynosVideoEncOps
*pEncOps
,
2154 ExynosVideoEncBufferOps
*pInbufOps
,
2155 ExynosVideoEncBufferOps
*pOutbufOps
)
2157 ExynosVideoErrorType ret
= VIDEO_ERROR_NONE
;
2159 if ((pEncOps
== NULL
) || (pInbufOps
== NULL
) || (pOutbufOps
== NULL
)) {
2160 ret
= VIDEO_ERROR_BADPARAM
;
2164 defEncOps
.nSize
= sizeof(defEncOps
);
2165 defInbufOps
.nSize
= sizeof(defInbufOps
);
2166 defOutbufOps
.nSize
= sizeof(defOutbufOps
);
2168 memcpy((char *)pEncOps
+ sizeof(pEncOps
->nSize
), (char *)&defEncOps
+ sizeof(defEncOps
.nSize
),
2169 pEncOps
->nSize
- sizeof(pEncOps
->nSize
));
2171 memcpy((char *)pInbufOps
+ sizeof(pInbufOps
->nSize
), (char *)&defInbufOps
+ sizeof(defInbufOps
.nSize
),
2172 pInbufOps
->nSize
- sizeof(pInbufOps
->nSize
));
2174 memcpy((char *)pOutbufOps
+ sizeof(pOutbufOps
->nSize
), (char *)&defOutbufOps
+ sizeof(defOutbufOps
.nSize
),
2175 pOutbufOps
->nSize
- sizeof(pOutbufOps
->nSize
));