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 #ifndef TIZEN_FEATURE_E3250 /* build env */
49 #include <utils/Log.h>
51 #include "Exynos_OSAL_Log.h"
54 #define MAX_CTRL_NUM 91
55 #define H264_CTRL_NUM 91
56 #define MPEG4_CTRL_NUM 26
57 #define H263_CTRL_NUM 18
59 /* FIXME: build error related with kernel-header pkg */
61 #ifndef V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR
62 #define V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_MFC_BASE + 46)
66 * [Common] __CodingType_To_V4L2PixelFormat
68 static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType)
70 unsigned int pixelformat = V4L2_PIX_FMT_H264;
73 case VIDEO_CODING_AVC:
74 pixelformat = V4L2_PIX_FMT_H264;
76 case VIDEO_CODING_MPEG4:
77 pixelformat = V4L2_PIX_FMT_MPEG4;
79 case VIDEO_CODING_VP8:
80 pixelformat = V4L2_PIX_FMT_VP8;
82 case VIDEO_CODING_H263:
83 pixelformat = V4L2_PIX_FMT_H263;
85 case VIDEO_CODING_VC1:
86 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G;
88 case VIDEO_CODING_VC1_RCV:
89 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L;
91 case VIDEO_CODING_MPEG2:
92 pixelformat = V4L2_PIX_FMT_MPEG2;
95 pixelformat = V4L2_PIX_FMT_H264;
103 * [Common] __ColorFormatType_To_V4L2PixelFormat
105 static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType)
107 unsigned int pixelformat = V4L2_PIX_FMT_NV12M;
109 switch (colorFormatType) {
110 case VIDEO_COLORFORMAT_NV12_TILED:
112 pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
114 pixelformat = V4L2_PIX_FMT_NV12MT;
118 case VIDEO_COLORFORMAT_NV21:
119 pixelformat = V4L2_PIX_FMT_NV21M;
122 case VIDEO_COLORFORMAT_NV12:
124 pixelformat = V4L2_PIX_FMT_NV12M;
134 static void *MFC_Encoder_Init(int nMemoryType)
136 ExynosVideoEncContext *pCtx = NULL;
137 pthread_mutex_t *pMutex = NULL;
138 int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING);
140 pCtx = (ExynosVideoEncContext *)malloc(sizeof(*pCtx));
142 ALOGE("%s: Failed to allocate encoder context buffer", __func__);
143 goto EXIT_ALLOC_FAIL;
146 memset(pCtx, 0, sizeof(*pCtx));
148 pCtx->hEnc = exynos_v4l2_open_devname(VIDEO_ENCODER_NAME, O_RDWR, 0);
149 if (pCtx->hEnc < 0) {
150 ALOGE("%s: Failed to open encoder device", __func__);
154 if (!exynos_v4l2_querycap(pCtx->hEnc, needCaps)) {
155 ALOGE("%s: Failed to querycap", __func__);
156 goto EXIT_QUERYCAP_FAIL;
159 pCtx->bStreamonInbuf = VIDEO_FALSE;
160 pCtx->bStreamonOutbuf = VIDEO_FALSE;
162 pCtx->nMemoryType = nMemoryType;
164 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
165 if (pMutex == NULL) {
166 ALOGE("%s: Failed to allocate mutex about input buffer", __func__);
167 goto EXIT_QUERYCAP_FAIL;
169 if (pthread_mutex_init(pMutex, NULL) != 0) {
171 goto EXIT_QUERYCAP_FAIL;
173 pCtx->pInMutex = (void*)pMutex;
175 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
176 if (pMutex == NULL) {
177 ALOGE("%s: Failed to allocate mutex about output buffer", __func__);
178 goto EXIT_QUERYCAP_FAIL;
180 if (pthread_mutex_init(pMutex, NULL) != 0) {
182 goto EXIT_QUERYCAP_FAIL;
184 pCtx->pOutMutex = (void*)pMutex;
189 if (pCtx->pInMutex != NULL) {
190 pthread_mutex_destroy(pCtx->pInMutex);
191 free(pCtx->pInMutex);
194 if (pCtx->pOutMutex != NULL) {
195 pthread_mutex_destroy(pCtx->pOutMutex);
196 free(pCtx->pOutMutex);
209 * [Encoder OPS] Finalize
211 static ExynosVideoErrorType MFC_Encoder_Finalize(void *pHandle)
213 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
214 ExynosVideoPlane *pVideoPlane = NULL;
215 pthread_mutex_t *pMutex = NULL;
216 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
220 ALOGE("%s: Video context info must be supplied", __func__);
221 ret = VIDEO_ERROR_BADPARAM;
225 if (pCtx->pOutMutex != NULL) {
226 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
227 pthread_mutex_destroy(pMutex);
229 pCtx->pOutMutex = NULL;
232 if (pCtx->pInMutex != NULL) {
233 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
234 pthread_mutex_destroy(pMutex);
236 pCtx->pInMutex = NULL;
239 if (pCtx->bShareInbuf == VIDEO_FALSE) {
240 for (i = 0; i < pCtx->nInbufs; i++) {
241 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
242 pVideoPlane = &pCtx->pInbuf[i].planes[j];
243 if (pVideoPlane->addr != NULL) {
244 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
245 pVideoPlane->addr = NULL;
246 pVideoPlane->allocSize = 0;
247 pVideoPlane->dataSize = 0;
250 pCtx->pInbuf[i].pGeometry = NULL;
251 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
252 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
257 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
258 for (i = 0; i < pCtx->nOutbufs; i++) {
259 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
260 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
261 if (pVideoPlane->addr != NULL) {
262 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
263 pVideoPlane->addr = NULL;
264 pVideoPlane->allocSize = 0;
265 pVideoPlane->dataSize = 0;
268 pCtx->pOutbuf[i].pGeometry = NULL;
269 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
270 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
275 if (pCtx->pInbuf != NULL)
278 if (pCtx->pOutbuf != NULL)
291 * [Encoder OPS] Set Extended Control
293 static ExynosVideoErrorType MFC_Encoder_Set_EncParam (
295 ExynosVideoEncParam *pEncParam)
297 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
298 ExynosVideoEncInitParam *pInitParam = NULL;
299 ExynosVideoEncCommonParam *pCommonParam = NULL;
301 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
304 struct v4l2_ext_control ext_ctrl[MAX_CTRL_NUM];
305 struct v4l2_ext_controls ext_ctrls;
308 if ((pCtx == NULL) || (pEncParam == NULL)) {
309 ALOGE("%s: Video context info must be supplied", __func__);
310 ret = VIDEO_ERROR_BADPARAM;
314 pInitParam = &pEncParam->initParam;
315 pCommonParam = &pEncParam->commonParam;
317 /* common parameters */
318 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
319 ext_ctrl[k++].value = pCommonParam->IDRPeriod;
320 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
321 ext_ctrl[k++].value = pCommonParam->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */
322 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB;
323 ext_ctrl[k++].value = pCommonParam->RandomIntraMBRefresh;
324 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING;
325 ext_ctrl[k++].value = pCommonParam->PadControlOn;
326 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV;
327 ext_ctrl[k].value = pCommonParam->CrPadVal;
328 ext_ctrl[k].value |= (pCommonParam->CbPadVal << 8);
329 ext_ctrl[k++].value |= (pCommonParam->LumaPadVal << 16);
330 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
331 ext_ctrl[k++].value = pCommonParam->EnableFRMRateControl;
332 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
333 ext_ctrl[k++].value = pCommonParam->EnableMBRateControl;
334 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_BITRATE;
336 /* FIXME temporary fix */
337 if (pCommonParam->Bitrate)
338 ext_ctrl[k++].value = pCommonParam->Bitrate;
340 ext_ctrl[k++].value = 1; /* just for testing Movie studio */
342 /* codec specific parameters */
343 switch (pEncParam->eCompressionFormat) {
344 case VIDEO_CODING_AVC:
346 ExynosVideoEncH264Param *pH264Param = &pEncParam->codecParam.h264;
348 /* common parameters but id is depends on codec */
349 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
350 ext_ctrl[k++].value = pCommonParam->FrameQp;
351 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
352 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
353 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
354 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
355 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
356 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
357 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
358 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
360 /* H.264 specific parameters */
361 switch (pCommonParam->SliceMode) {
363 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
364 ext_ctrl[k++].value = 1; /* default */
365 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
366 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
369 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
370 ext_ctrl[k++].value = pH264Param->SliceArgument;
371 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
372 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
374 case 2: /* Fixed Byte number Slice mode */
375 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
376 ext_ctrl[k++].value = 1; /* default */
377 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
378 ext_ctrl[k++].value = pH264Param->SliceArgument;
384 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
385 ext_ctrl[k++].value = pH264Param->ProfileIDC;
386 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
387 ext_ctrl[k++].value = pH264Param->LevelIDC;
388 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P;
389 ext_ctrl[k++].value = pH264Param->NumberRefForPframes;
391 * It should be set using h264Param->NumberBFrames after being handled by appl.
393 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
394 ext_ctrl[k++].value = pH264Param->NumberBFrames;
395 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
396 ext_ctrl[k++].value = pH264Param->LoopFilterDisable;
397 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
398 ext_ctrl[k++].value = pH264Param->LoopFilterAlphaC0Offset;
399 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
400 ext_ctrl[k++].value = pH264Param->LoopFilterBetaOffset;
401 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
402 ext_ctrl[k++].value = pH264Param->SymbolMode;
403 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE
404 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE;
405 ext_ctrl[k++].value = pH264Param->PictureInterlace;
407 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM;
408 ext_ctrl[k++].value = pH264Param->Transform8x8Mode;
409 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE
410 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE;
411 ext_ctrl[k++].value = pH264Param->FrameRate;
413 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
414 ext_ctrl[k++].value = pH264Param->FrameQp_B;
416 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK;
417 ext_ctrl[k++].value = pH264Param->DarkDisable;
418 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH;
419 ext_ctrl[k++].value = pH264Param->SmoothDisable;
420 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC;
421 ext_ctrl[k++].value = pH264Param->StaticDisable;
422 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY;
423 ext_ctrl[k++].value = pH264Param->ActivityDisable;
425 /* doesn't have to be set */
426 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE;
427 ext_ctrl[k++].value = 1;
428 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD;
429 ext_ctrl[k++].value = 10;
430 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
431 ext_ctrl[k++].value = 0;
432 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
433 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; /* 0: seperated header, 1: header + first frame */
434 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE;
435 ext_ctrl[k++].value = 0;
436 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC;
437 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED;
438 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH;
439 ext_ctrl[k++].value = 0;
440 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT;
441 ext_ctrl[k++].value = 0;
443 /* Initial parameters : Frame Skip */
444 switch (pInitParam->FrameSkip) {
445 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
447 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
448 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
450 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
451 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
452 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
455 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
456 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
457 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
461 /* SVC is not supported yet */
462 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING;
463 ext_ctrl[k++].value = 0;
464 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
465 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B;
466 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
467 ext_ctrl[k++].value = 3;
468 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
469 ext_ctrl[k++].value = (0 << 16 | 0);
470 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
471 ext_ctrl[k++].value = (1 << 16 | 0);
472 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
473 ext_ctrl[k++].value = (2 << 16 | 0);
474 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING;
475 ext_ctrl[k++].value = 0;
476 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0;
477 ext_ctrl[k++].value = 0;
478 #ifdef V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE
479 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE;
480 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE;
482 /* FMO is not supported yet */
483 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO;
484 ext_ctrl[k++].value = 0;
485 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE;
486 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES;
487 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP;
488 ext_ctrl[k++].value = 4;
489 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
490 ext_ctrl[k++].value = (0 << 30 | 0);
491 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
492 ext_ctrl[k++].value = (1 << 30 | 0);
493 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
494 ext_ctrl[k++].value = (2 << 30 | 0);
495 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
496 ext_ctrl[k++].value = (3 << 30 | 0);
497 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION;
498 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT;
499 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE;
500 ext_ctrl[k++].value = 0;
502 /* ASO is not supported yet */
503 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO;
504 ext_ctrl[k++].value = 0;
506 for (i = 0; i < 32; i++) {
507 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER;
508 ext_ctrl[k++].value = (i << 16 | 0);
511 ext_ctrls.count = H264_CTRL_NUM;
515 case VIDEO_CODING_MPEG4:
517 ExynosVideoEncMpeg4Param *pMpeg4Param = &pEncParam->codecParam.mpeg4;
519 /* common parameters but id is depends on codec */
520 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP;
521 ext_ctrl[k++].value = pCommonParam->FrameQp;
522 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP;
523 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
524 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP;
525 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
526 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP;
527 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
528 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
529 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
531 /* MPEG4 specific parameters */
532 switch (pCommonParam->SliceMode) {
534 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
535 ext_ctrl[k++].value = 1; /* default */
536 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
537 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
540 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
541 ext_ctrl[k++].value = pMpeg4Param->SliceArgument;
542 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
543 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
546 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
547 ext_ctrl[k++].value = 1; /* default */
548 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
549 ext_ctrl[k++].value = pMpeg4Param->SliceArgument;
555 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
556 ext_ctrl[k++].value = pMpeg4Param->ProfileIDC;
557 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
558 ext_ctrl[k++].value = pMpeg4Param->LevelIDC;
559 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL;
560 ext_ctrl[k++].value = pMpeg4Param->DisableQpelME;
563 * It should be set using mpeg4Param->NumberBFrames after being handled by appl.
565 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
566 ext_ctrl[k++].value = pMpeg4Param->NumberBFrames;
567 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES
568 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES;
569 ext_ctrl[k++].value = pMpeg4Param->TimeIncreamentRes;
571 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA
572 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA;
573 ext_ctrl[k++].value = pMpeg4Param->VopTimeIncreament;
575 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP;
576 ext_ctrl[k++].value = pMpeg4Param->FrameQp_B;
577 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
578 ext_ctrl[k++].value = 0;
579 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
580 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
581 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
582 ext_ctrl[k++].value = 1;
584 /* Initial parameters : Frame Skip */
585 switch (pInitParam->FrameSkip) {
586 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
587 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
588 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
590 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
591 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
592 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
595 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
596 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
597 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
601 ext_ctrls.count = MPEG4_CTRL_NUM;
605 case VIDEO_CODING_H263:
607 ExynosVideoEncH263Param *pH263Param = &pEncParam->codecParam.h263;
609 /* common parameters but id is depends on codec */
610 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP;
611 ext_ctrl[k++].value = pCommonParam->FrameQp;
612 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP;
613 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
614 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP;
615 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
616 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP;
617 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
618 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
619 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
621 /* H263 specific parameters */
622 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE
623 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE;
624 ext_ctrl[k++].value = pH263Param->FrameRate;
626 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
627 ext_ctrl[k++].value = 0;
628 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
629 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
630 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
631 ext_ctrl[k++].value = 1;
633 /* Initial parameters : Frame Skip */
634 switch (pInitParam->FrameSkip) {
635 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
636 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
637 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
639 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
640 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
641 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
644 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
645 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
646 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
649 ext_ctrls.count = H263_CTRL_NUM;
654 ALOGE("[%s] Undefined codec type",__func__);
655 ret = VIDEO_ERROR_BADPARAM;
659 ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
660 ext_ctrls.controls = ext_ctrl;
662 if (exynos_v4l2_s_ext_ctrl(pCtx->hEnc, &ext_ctrls) != 0) {
663 ALOGE("%s: Failed to s_ext_ctrl", __func__);
664 ret = VIDEO_ERROR_APIFAIL;
673 * [Encoder OPS] Set Frame Tag
675 static ExynosVideoErrorType MFC_Encoder_Set_FrameTag(
679 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
680 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
683 ALOGE("%s: Video context info must be supplied", __func__);
684 ret = VIDEO_ERROR_BADPARAM;
687 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
688 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) {
689 ALOGE("%s: Failed to s_ctrl", __func__);
690 ret = VIDEO_ERROR_APIFAIL;
699 * [Encoder OPS] Get Frame Tag
701 static int MFC_Encoder_Get_FrameTag(void *pHandle)
703 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
704 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
709 ALOGE("%s: Video context info must be supplied", __func__);
712 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
713 if (exynos_v4l2_g_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag) != 0) {
714 ALOGE("%s: Failed to g_ctrl", __func__);
715 ret = VIDEO_ERROR_APIFAIL;
724 * [Encoder OPS] Set Frame Type
726 static ExynosVideoErrorType MFC_Encoder_Set_FrameType(
728 ExynosVideoFrameType frameType)
730 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
731 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
734 ALOGE("%s: Video context info must be supplied", __func__);
735 ret = VIDEO_ERROR_BADPARAM;
740 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE, frameType) != 0) {
741 ALOGE("%s: Failed to s_ctrl", __func__);
742 ret = VIDEO_ERROR_APIFAIL;
752 * [Encoder OPS] Set Frame Rate
754 static ExynosVideoErrorType MFC_Encoder_Set_FrameRate(
758 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
759 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
762 ALOGE("%s: Video context info must be supplied", __func__);
763 ret = VIDEO_ERROR_BADPARAM;
766 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH
767 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH, frameRate) != 0) {
768 ALOGE("%s: Failed to s_ctrl", __func__);
769 ret = VIDEO_ERROR_APIFAIL;
779 * [Encoder OPS] Set Bit Rate
781 static ExynosVideoErrorType MFC_Encoder_Set_BitRate(
785 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
786 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
789 ALOGE("%s: Video context info must be supplied", __func__);
790 ret = VIDEO_ERROR_BADPARAM;
793 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH
794 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH, bitRate) != 0) {
795 ALOGE("%s: Failed to s_ctrl", __func__);
796 ret = VIDEO_ERROR_APIFAIL;
805 * [Encoder OPS] Set Frame Skip
807 static ExynosVideoErrorType MFC_Encoder_Set_FrameSkip(
811 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
812 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
815 ALOGE("%s: Video context info must be supplied", __func__);
816 ret = VIDEO_ERROR_BADPARAM;
820 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE, frameSkip) != 0) {
821 ALOGE("%s: Failed to s_ctrl", __func__);
822 ret = VIDEO_ERROR_APIFAIL;
831 * [Encoder OPS] Set IDR Period
833 static ExynosVideoErrorType MFC_Encoder_Set_IDRPeriod(
837 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
838 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
841 ALOGE("%s: Video context info must be supplied", __func__);
842 ret = VIDEO_ERROR_BADPARAM;
846 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, IDRPeriod) != 0) {
847 ALOGE("%s: Failed to s_ctrl", __func__);
848 ret = VIDEO_ERROR_APIFAIL;
857 * [Encoder OPS] Enable Prepend SPS and PPS to every IDR Frames
859 static ExynosVideoErrorType MFC_Encoder_Enable_PrependSpsPpsToIdr(void *pHandle)
861 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
862 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
865 ALOGE("%s: Video context info must be supplied", __func__);
866 ret = VIDEO_ERROR_BADPARAM;
869 #ifdef V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR
870 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR, 1) != 0) {
871 ALOGE("%s: Failed to s_ctrl", __func__);
872 ret = VIDEO_ERROR_APIFAIL;
881 * [Encoder Buffer OPS] Enable Cacheable (Input)
883 static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Inbuf(void *pHandle)
885 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
886 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
889 ALOGE("%s: Video context info must be supplied", __func__);
890 ret = VIDEO_ERROR_BADPARAM;
893 #ifdef V4L2_CID_CACHEABLE
894 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 2) != 0) {
895 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__);
896 ret = VIDEO_ERROR_APIFAIL;
905 * [Encoder Buffer OPS] Enable Cacheable (Output)
907 static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Outbuf(void *pHandle)
909 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
910 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
913 ALOGE("%s: Video context info must be supplied", __func__);
914 ret = VIDEO_ERROR_BADPARAM;
917 #ifdef V4L2_CID_CACHEABLE
918 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 1) != 0) {
919 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__);
920 ret = VIDEO_ERROR_APIFAIL;
929 * [Encoder Buffer OPS] Set Shareable Buffer (Input)
931 static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Inbuf(void *pHandle)
933 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
934 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
937 ALOGE("%s: Video context info must be supplied", __func__);
938 ret = VIDEO_ERROR_BADPARAM;
942 pCtx->bShareInbuf = VIDEO_TRUE;
949 * [Encoder Buffer OPS] Set Shareable Buffer (Output)
951 static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Outbuf(void *pHandle)
953 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
954 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
957 ALOGE("%s: Video context info must be supplied", __func__);
958 ret = VIDEO_ERROR_BADPARAM;
962 pCtx->bShareOutbuf = VIDEO_TRUE;
969 * [Encoder Buffer OPS] Get Buffer (Input)
971 static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Inbuf(
974 ExynosVideoBuffer **pBuffer)
976 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
977 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
980 ALOGE("%s: Video context info must be supplied", __func__);
982 ret = VIDEO_ERROR_NOBUFFERS;
986 if (pCtx->nInbufs <= nIndex) {
988 ret = VIDEO_ERROR_BADPARAM;
992 *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex];
999 * [Encoder Buffer OPS] Get Buffer (Output)
1001 static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Outbuf(
1004 ExynosVideoBuffer **pBuffer)
1006 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1007 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1010 ALOGE("%s: Video context info must be supplied", __func__);
1012 ret = VIDEO_ERROR_NOBUFFERS;
1016 if (pCtx->nOutbufs <= nIndex) {
1018 ret = VIDEO_ERROR_BADPARAM;
1022 *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex];
1029 * [Encoder Buffer OPS] Set Geometry (Src)
1031 static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Inbuf(
1033 ExynosVideoGeometry *bufferConf)
1035 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1036 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1038 struct v4l2_format fmt;
1041 ALOGE("%s: Video context info must be supplied", __func__);
1042 ret = VIDEO_ERROR_BADPARAM;
1046 if (bufferConf == NULL) {
1047 ALOGE("%s: Buffer geometry must be supplied", __func__);
1048 ret = VIDEO_ERROR_BADPARAM;
1052 memset(&fmt, 0, sizeof(fmt));
1054 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1055 fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat);
1056 fmt.fmt.pix_mp.width = bufferConf->nFrameWidth;
1057 fmt.fmt.pix_mp.height = bufferConf->nFrameHeight;
1058 fmt.fmt.pix_mp.num_planes = VIDEO_ENCODER_INBUF_PLANES;
1061 if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) {
1062 ALOGE("%s: Failed to s_fmt", __func__);
1063 ret = VIDEO_ERROR_APIFAIL;
1067 memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry));
1074 * [Encoder Buffer OPS] Get Geometry (Src)
1076 static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Inbuf(
1078 ExynosVideoGeometry *bufferConf)
1080 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1081 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1083 struct v4l2_format fmt;
1086 ALOGE("%s: Video context info must be supplied", __func__);
1087 ret = VIDEO_ERROR_BADPARAM;
1091 if (bufferConf == NULL) {
1092 ALOGE("%s: Buffer geometry must be supplied", __func__);
1093 ret = VIDEO_ERROR_BADPARAM;
1097 memset(&fmt, 0, sizeof(fmt));
1099 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1100 if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) {
1101 ALOGE("%s: Failed to g_fmt", __func__);
1102 ret = VIDEO_ERROR_APIFAIL;
1106 bufferConf->nFrameHeight = fmt.fmt.pix_mp.width;
1107 bufferConf->nFrameHeight = fmt.fmt.pix_mp.height;
1108 bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1115 * [Encoder Buffer OPS] Set Geometry (Dst)
1117 static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Outbuf(
1119 ExynosVideoGeometry *bufferConf)
1121 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1122 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1124 struct v4l2_format fmt;
1127 ALOGE("%s: Video context info must be supplied", __func__);
1128 ret = VIDEO_ERROR_BADPARAM;
1132 if (bufferConf == NULL) {
1133 ALOGE("%s: Buffer geometry must be supplied", __func__);
1134 ret = VIDEO_ERROR_BADPARAM;
1138 memset(&fmt, 0, sizeof(fmt));
1140 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1141 fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat);
1142 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage;
1144 if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) {
1145 ALOGE("%s: Failed to s_fmt", __func__);
1146 ret = VIDEO_ERROR_APIFAIL;
1150 memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry));
1157 * [Encoder Buffer OPS] Get Geometry (Dst)
1159 static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Outbuf(
1161 ExynosVideoGeometry *bufferConf)
1163 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1164 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1166 struct v4l2_format fmt;
1169 ALOGE("%s: Video context info must be supplied", __func__);
1170 ret = VIDEO_ERROR_BADPARAM;
1174 if (bufferConf == NULL) {
1175 ALOGE("%s: Buffer geometry must be supplied", __func__);
1176 ret = VIDEO_ERROR_BADPARAM;
1180 memset(&fmt, 0, sizeof(fmt));
1182 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1183 if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) {
1184 ALOGE("%s: Failed to g_fmt", __func__);
1185 ret = VIDEO_ERROR_APIFAIL;
1190 bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1197 * [Encoder Buffer OPS] Setup (Src)
1199 static ExynosVideoErrorType MFC_Encoder_Setup_Inbuf(
1201 unsigned int nBufferCount)
1203 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1204 ExynosVideoPlane *pVideoPlane = NULL;
1205 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1207 struct v4l2_requestbuffers req;
1208 struct v4l2_buffer buf;
1209 struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES];
1213 ALOGE("%s: Video context info must be supplied", __func__);
1214 ret = VIDEO_ERROR_BADPARAM;
1218 if (nBufferCount == 0) {
1219 ALOGE("%s: Buffer count must be greater than 0", __func__);
1220 ret = VIDEO_ERROR_BADPARAM;
1224 memset(&req, 0, sizeof(req));
1226 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1227 req.count = nBufferCount;
1229 if (pCtx->bShareInbuf == VIDEO_TRUE)
1230 req.memory = pCtx->nMemoryType;
1232 req.memory = V4L2_MEMORY_MMAP;
1234 if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) {
1235 ALOGE("Failed to require buffer");
1236 ret = VIDEO_ERROR_APIFAIL;
1240 pCtx->nInbufs = (int)req.count;
1242 pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
1243 if (pCtx->pInbuf == NULL) {
1244 ALOGE("%s: Failed to allocate input buffer context", __func__);
1245 ret = VIDEO_ERROR_NOMEM;
1248 memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
1250 memset(&buf, 0, sizeof(buf));
1252 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1253 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1254 buf.memory = V4L2_MEMORY_MMAP;
1255 buf.m.planes = planes;
1256 buf.length = VIDEO_ENCODER_INBUF_PLANES;
1258 for (i = 0; i < pCtx->nInbufs; i++) {
1260 if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) {
1261 ALOGE("%s: Failed to querybuf", __func__);
1262 ret = VIDEO_ERROR_APIFAIL;
1266 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
1267 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1268 pVideoPlane->addr = mmap(NULL,
1269 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1270 MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset);
1272 if (pVideoPlane->addr == MAP_FAILED) {
1273 ALOGE("%s: Failed to map", __func__);
1274 ret = VIDEO_ERROR_MAPFAIL;
1278 pVideoPlane->allocSize = buf.m.planes[j].length;
1279 pVideoPlane->dataSize = 0;
1282 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
1283 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1284 pCtx->pInbuf[i].bRegistered = VIDEO_TRUE;
1288 for (i = 0; i < pCtx->nInbufs; i++) {
1289 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
1290 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1291 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
1298 if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) {
1299 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1300 for (i = 0; i < pCtx->nInbufs; i++) {
1301 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
1302 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1303 if (pVideoPlane->addr == MAP_FAILED) {
1304 pVideoPlane->addr = NULL;
1308 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1320 * [Encoder Buffer OPS] Setup (Dst)
1322 static ExynosVideoErrorType MFC_Encoder_Setup_Outbuf(
1324 unsigned int nBufferCount)
1326 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1327 ExynosVideoPlane *pVideoPlane = NULL;
1328 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1330 struct v4l2_requestbuffers req;
1331 struct v4l2_buffer buf;
1332 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
1336 ALOGE("%s: Video context info must be supplied", __func__);
1337 ret = VIDEO_ERROR_BADPARAM;
1341 if (nBufferCount == 0) {
1342 ALOGE("%s: Buffer count must be greater than 0", __func__);
1343 ret = VIDEO_ERROR_BADPARAM;
1347 memset(&req, 0, sizeof(req));
1349 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1350 req.count = nBufferCount;
1352 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1353 req.memory = pCtx->nMemoryType;
1355 req.memory = V4L2_MEMORY_MMAP;
1357 if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) {
1358 ALOGE("%s: Failed to reqbuf", __func__);
1359 ret = VIDEO_ERROR_APIFAIL;
1363 pCtx->nOutbufs = req.count;
1365 pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1366 if (pCtx->pOutbuf == NULL) {
1367 ALOGE("%s: Failed to allocate output buffer context", __func__);
1368 ret = VIDEO_ERROR_NOMEM;
1371 memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1373 memset(&buf, 0, sizeof(buf));
1375 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1376 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1377 buf.memory = V4L2_MEMORY_MMAP;
1378 buf.m.planes = planes;
1379 buf.length = VIDEO_ENCODER_OUTBUF_PLANES;
1381 for (i = 0; i < pCtx->nOutbufs; i++) {
1383 if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) {
1384 ALOGE("%s: Failed to querybuf", __func__);
1385 ret = VIDEO_ERROR_APIFAIL;
1389 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
1390 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1391 pVideoPlane->addr = mmap(NULL,
1392 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1393 MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset);
1395 if (pVideoPlane->addr == MAP_FAILED) {
1396 ALOGE("%s: Failed to map", __func__);
1397 ret = VIDEO_ERROR_MAPFAIL;
1401 pVideoPlane->allocSize = buf.m.planes[j].length;
1402 pVideoPlane->dataSize = 0;
1405 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1406 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1407 pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE;
1410 for (i = 0; i < pCtx->nOutbufs; i++ ) {
1411 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1412 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1413 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
1420 if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) {
1421 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1422 for (i = 0; i < pCtx->nOutbufs; i++) {
1423 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
1424 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1425 if (pVideoPlane->addr == MAP_FAILED) {
1426 pVideoPlane->addr = NULL;
1430 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1435 free(pCtx->pOutbuf);
1442 * [Encoder Buffer OPS] Run (src)
1444 static ExynosVideoErrorType MFC_Encoder_Run_Inbuf(void *pHandle)
1446 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1447 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1450 ALOGE("%s: Video context info must be supplied", __func__);
1451 ret = VIDEO_ERROR_BADPARAM;
1455 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1456 if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1457 ALOGE("%s: Failed to streamon for input buffer", __func__);
1458 ret = VIDEO_ERROR_APIFAIL;
1461 pCtx->bStreamonInbuf = VIDEO_TRUE;
1469 * [Encoder Buffer OPS] Run (Dst)
1471 static ExynosVideoErrorType MFC_Encoder_Run_Outbuf(void *pHandle)
1473 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1474 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1477 ALOGE("%s: Video context info must be supplied", __func__);
1478 ret = VIDEO_ERROR_BADPARAM;
1482 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1483 if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1484 ALOGE("%s: Failed to streamon for output buffer", __func__);
1485 ret = VIDEO_ERROR_APIFAIL;
1488 pCtx->bStreamonOutbuf = VIDEO_TRUE;
1496 * [Encoder Buffer OPS] Stop (Src)
1498 static ExynosVideoErrorType MFC_Encoder_Stop_Inbuf(void *pHandle)
1500 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1501 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1505 ALOGE("%s: Video context info must be supplied", __func__);
1506 ret = VIDEO_ERROR_BADPARAM;
1510 if (pCtx->bStreamonInbuf == VIDEO_TRUE) {
1511 if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1512 ALOGE("%s: Failed to streamoff for input buffer", __func__);
1513 ret = VIDEO_ERROR_APIFAIL;
1516 pCtx->bStreamonInbuf = VIDEO_FALSE;
1519 for (i = 0; i < pCtx->nInbufs; i++) {
1520 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1528 * [Encoder Buffer OPS] Stop (Dst)
1530 static ExynosVideoErrorType MFC_Encoder_Stop_Outbuf(void *pHandle)
1532 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1533 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1537 ALOGE("%s: Video context info must be supplied", __func__);
1538 ret = VIDEO_ERROR_BADPARAM;
1542 if (pCtx->bStreamonOutbuf == VIDEO_TRUE) {
1543 if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1544 ALOGE("%s: Failed to streamoff for output buffer", __func__);
1545 ret = VIDEO_ERROR_APIFAIL;
1548 pCtx->bStreamonOutbuf = VIDEO_FALSE;
1551 for (i = 0; i < pCtx->nOutbufs; i++) {
1552 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1560 * [Encoder Buffer OPS] Wait (Src)
1562 static ExynosVideoErrorType MFC_Encoder_Wait_Inbuf(void *pHandle)
1564 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1565 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1567 struct pollfd poll_events;
1571 ALOGE("%s: Video context info must be supplied", __func__);
1572 ret = VIDEO_ERROR_BADPARAM;
1576 poll_events.fd = pCtx->hEnc;
1577 poll_events.events = POLLOUT | POLLERR;
1578 poll_events.revents = 0;
1581 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
1582 if (poll_state > 0) {
1583 if (poll_events.revents & POLLOUT) {
1586 ALOGE("%s: Poll return error", __func__);
1587 ret = VIDEO_ERROR_POLL;
1590 } else if (poll_state < 0) {
1591 ALOGE("%s: Poll state error", __func__);
1592 ret = VIDEO_ERROR_POLL;
1595 } while (poll_state == 0);
1602 * [Encoder Buffer OPS] Wait (Dst)
1604 static ExynosVideoErrorType MFC_Encoder_Wait_Outbuf(void *pHandle)
1606 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1607 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1609 struct pollfd poll_events;
1611 int bframe_count = 0; // FIXME
1614 ALOGE("%s: Video context info must be supplied", __func__);
1615 ret = VIDEO_ERROR_BADPARAM;
1619 poll_events.fd = pCtx->hEnc;
1620 poll_events.events = POLLIN | POLLERR;
1621 poll_events.revents = 0;
1624 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
1625 if (poll_state > 0) {
1626 if (poll_events.revents & POLLIN) {
1629 ALOGE("%s: Poll return error", __func__);
1630 ret = VIDEO_ERROR_POLL;
1633 } else if (poll_state < 0) {
1634 ALOGE("%s: Poll state error", __func__);
1635 ret = VIDEO_ERROR_POLL;
1638 bframe_count++; // FIXME
1640 } while (poll_state == 0 && bframe_count < 5); // FIXME
1646 static ExynosVideoErrorType MFC_Encoder_Register_Inbuf(
1648 ExynosVideoPlane *planes,
1651 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1652 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1655 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_INBUF_PLANES)) {
1656 ALOGE("%s: input params must be supplied", __func__);
1657 ret = VIDEO_ERROR_BADPARAM;
1661 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1662 if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) {
1664 for (plane = 0; plane < nPlanes; plane++) {
1665 pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr;
1666 pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1667 pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd;
1668 ALOGV("%s: addr = 0x%x", __func__, pCtx->pInbuf[nIndex].planes[plane].addr);
1670 pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE;
1675 if (nIndex == pCtx->nInbufs) {
1676 ALOGE("%s: can not find non-registered input buffer", __func__);
1677 ret = VIDEO_ERROR_NOBUFFERS;
1684 static ExynosVideoErrorType MFC_Encoder_Register_Outbuf(
1686 ExynosVideoPlane *planes,
1689 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1690 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1693 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_OUTBUF_PLANES)) {
1694 ALOGE("%s: params must be supplied", __func__);
1695 ret = VIDEO_ERROR_BADPARAM;
1699 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1700 if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) {
1702 for (plane = 0; plane < nPlanes; plane++) {
1703 pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr;
1704 pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1705 pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd;
1707 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE;
1712 if (nIndex == pCtx->nOutbufs) {
1713 ALOGE("%s: can not find non-registered output buffer", __func__);
1714 ret = VIDEO_ERROR_NOBUFFERS;
1721 static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
1723 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1724 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1728 ALOGE("%s: Video context info must be supplied", __func__);
1729 ret = VIDEO_ERROR_BADPARAM;
1733 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1734 pCtx->pInbuf[nIndex].planes[0].addr = NULL;
1735 pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE;
1742 static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
1744 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1745 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1749 ALOGE("%s: Video context info must be supplied", __func__);
1750 ret = VIDEO_ERROR_BADPARAM;
1754 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1755 pCtx->pOutbuf[nIndex].planes[0].addr = NULL;
1756 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE;
1764 * [Encoder Buffer OPS] Find (Input)
1766 static int MFC_Encoder_Find_Inbuf(
1768 unsigned char *pBuffer)
1770 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1774 ALOGE("%s: Video context info must be supplied", __func__);
1778 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1779 if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) {
1780 if ((pBuffer == NULL) ||
1781 (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer))
1786 if (nIndex == pCtx->nInbufs)
1794 * [Encoder Buffer OPS] Find (Output)
1796 static int MFC_Encoder_Find_Outbuf(
1798 unsigned char *pBuffer)
1800 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1804 ALOGE("%s: Video context info must be supplied", __func__);
1808 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1809 if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) {
1810 if ((pBuffer == NULL) ||
1811 (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer))
1816 if (nIndex == pCtx->nOutbufs)
1824 * [Encoder Buffer OPS] Enqueue (Input)
1826 static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf(
1828 unsigned char *pBuffer[],
1829 unsigned int dataSize[],
1833 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1834 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1835 pthread_mutex_t *pMutex = NULL;
1837 struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES];
1838 struct v4l2_buffer buf;
1842 ALOGE("%s: Video context info must be supplied", __func__);
1843 ret = VIDEO_ERROR_BADPARAM;
1847 if (VIDEO_ENCODER_INBUF_PLANES < nPlanes) {
1848 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1849 VIDEO_ENCODER_INBUF_PLANES, nPlanes);
1850 ret = VIDEO_ERROR_BADPARAM;
1854 memset(&planes,0,sizeof(planes));
1855 memset(&buf, 0, sizeof(buf));
1857 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1858 buf.m.planes = planes;
1859 buf.length = VIDEO_ENCODER_INBUF_PLANES;
1861 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
1862 pthread_mutex_lock(pMutex);
1863 index = MFC_Encoder_Find_Inbuf(pCtx, pBuffer[0]);
1865 pthread_mutex_unlock(pMutex);
1866 ALOGE("%s: Failed to get index", __func__);
1867 ret = VIDEO_ERROR_NOBUFFERS;
1872 pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE;
1873 pthread_mutex_unlock(pMutex);
1875 if (pCtx->bShareInbuf == VIDEO_TRUE) {
1876 buf.memory = pCtx->nMemoryType;
1878 for (i = 0; i < nPlanes; i++) {
1879 /* V4L2_MEMORY_USERPTR */
1880 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1881 buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize;
1882 /* V4L2_MEMORY_DMABUF */
1883 #ifdef TIZEN_FEATURE_E3250 /* #ifdef USE_DMA_BUF */
1884 buf.m.planes[i].m.fd = pCtx->pInbuf[buf.index].planes[i].fd;
1885 buf.m.planes[i].length = 0; /* kernel give the length */
1887 buf.m.planes[i].bytesused = dataSize[i];
1890 buf.memory = V4L2_MEMORY_MMAP;
1891 for (i = 0; i < nPlanes; i++)
1892 buf.m.planes[i].bytesused = dataSize[i];
1895 ALOGE("call exynos_v4l2_qbuf(): %d", buf.m.planes[0].m.fd);
1896 if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) {
1897 ALOGE("%s: Failed to enqueue input buffer", __func__);
1898 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1899 ret = VIDEO_ERROR_APIFAIL;
1903 pCtx->pInbuf[buf.index].pPrivate = pPrivate;
1910 * [Encoder Buffer OPS] Enqueue (Output)
1912 static ExynosVideoErrorType MFC_Encoder_Enqueue_Outbuf(
1914 unsigned char *pBuffer[],
1915 unsigned int dataSize[],
1919 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1920 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1921 pthread_mutex_t *pMutex = NULL;
1923 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
1924 struct v4l2_buffer buf;
1928 ALOGE("%s: Video context info must be supplied", __func__);
1929 ret = VIDEO_ERROR_BADPARAM;
1933 if (VIDEO_ENCODER_OUTBUF_PLANES < nPlanes) {
1934 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1935 VIDEO_ENCODER_OUTBUF_PLANES, nPlanes);
1936 ret = VIDEO_ERROR_BADPARAM;
1940 memset(&buf, 0, sizeof(buf));
1942 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1943 buf.m.planes = planes;
1944 buf.length = VIDEO_ENCODER_OUTBUF_PLANES;
1946 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
1947 pthread_mutex_lock(pMutex);
1948 index = MFC_Encoder_Find_Outbuf(pCtx, pBuffer[0]);
1950 pthread_mutex_unlock(pMutex);
1951 ALOGE("%s: Failed to get index", __func__);
1952 ret = VIDEO_ERROR_NOBUFFERS;
1956 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE;
1957 pthread_mutex_unlock(pMutex);
1959 if (pCtx->bShareOutbuf == VIDEO_TRUE) {
1960 buf.memory = pCtx->nMemoryType;
1961 for (i = 0; i < nPlanes; i++) {
1962 /* V4L2_MEMORY_USERPTR */
1963 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1964 buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize;
1965 /* V4L2_MEMORY_DMABUF */
1967 buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd;
1968 buf.m.planes[i].length = 0; /* kernel give the length */
1970 buf.m.planes[i].bytesused = dataSize[i];
1973 buf.memory = V4L2_MEMORY_MMAP;
1976 if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) {
1977 ALOGE("%s: Failed to enqueue output buffer", __func__);
1978 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE;
1979 ret = VIDEO_ERROR_APIFAIL;
1983 pCtx->pOutbuf[buf.index].pPrivate = pPrivate;
1990 * [Encoder Buffer OPS] Enqueue All (Output)
1992 static ExynosVideoErrorType MFC_Encoder_Enqueue_All_Outbuf(void *pHandle)
1994 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1995 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1997 unsigned char *pBuffer[VIDEO_BUFFER_MAX_PLANES] = {NULL, };
1998 unsigned int dataSize[VIDEO_BUFFER_MAX_PLANES] = {0, };
2003 ALOGE("%s: Video context info must be supplied", __func__);
2004 ret = VIDEO_ERROR_BADPARAM;
2008 for (i = 0; i < pCtx->nOutbufs; i++) {
2009 ret = MFC_Encoder_Enqueue_Outbuf(pCtx, pBuffer, dataSize, 1, NULL);
2010 if (ret != VIDEO_ERROR_NONE)
2019 * [Encoder Buffer OPS] Dequeue (Input)
2021 static ExynosVideoBuffer *MFC_Encoder_Dequeue_Inbuf(void *pHandle)
2023 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2024 ExynosVideoBuffer *pInbuf = NULL;
2026 struct v4l2_buffer buf;
2029 ALOGE("%s: Video context info must be supplied", __func__);
2033 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
2038 memset(&buf, 0, sizeof(buf));
2040 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2042 if (pCtx->bShareInbuf == VIDEO_TRUE)
2043 buf.memory = pCtx->nMemoryType;
2045 buf.memory = V4L2_MEMORY_MMAP;
2047 if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) {
2052 pInbuf = &pCtx->pInbuf[buf.index];
2053 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
2060 * [Encoder Buffer OPS] Dequeue (Output)
2062 static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle)
2064 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2065 ExynosVideoBuffer *pOutbuf = NULL;
2067 struct v4l2_buffer buf;
2068 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
2072 ALOGE("%s: Video context info must be supplied", __func__);
2076 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
2081 memset(&buf, 0, sizeof(buf));
2083 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2084 buf.m.planes = planes;
2087 if (pCtx->bShareOutbuf == VIDEO_TRUE)
2088 buf.memory = pCtx->nMemoryType;
2090 buf.memory = V4L2_MEMORY_MMAP;
2092 /* no error case for output buffer dequeue in encoder */
2093 if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) {
2097 pOutbuf = &pCtx->pOutbuf[buf.index];
2098 pOutbuf->planes[0].dataSize = buf.m.planes[0].bytesused;
2100 switch (buf.flags & (0x7 << 3)) {
2101 case V4L2_BUF_FLAG_KEYFRAME:
2102 pOutbuf->frameType = VIDEO_FRAME_I;
2104 case V4L2_BUF_FLAG_PFRAME:
2105 pOutbuf->frameType = VIDEO_FRAME_P;
2107 case V4L2_BUF_FLAG_BFRAME:
2108 pOutbuf->frameType = VIDEO_FRAME_B;
2111 ALOGI("%s: encoded frame type is = %d",__func__, (buf.flags & (0x7 << 3)));
2112 pOutbuf->frameType = VIDEO_FRAME_OTHERS;
2116 pOutbuf->bQueued = VIDEO_FALSE;
2122 static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Inbuf(void *pHandle)
2124 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2125 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2129 ALOGE("%s: Video context info must be supplied", __func__);
2130 ret = VIDEO_ERROR_BADPARAM;
2134 for (i = 0; i < pCtx->nInbufs; i++) {
2135 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
2142 static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Outbuf(void *pHandle)
2144 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2145 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2149 ALOGE("%s: Video context info must be supplied", __func__);
2150 ret = VIDEO_ERROR_BADPARAM;
2154 for (i = 0; i < pCtx->nOutbufs; i++) {
2155 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
2163 * [Encoder OPS] Common
2165 static ExynosVideoEncOps defEncOps = {
2167 .Init = MFC_Encoder_Init,
2168 .Finalize = MFC_Encoder_Finalize,
2169 .Set_EncParam = MFC_Encoder_Set_EncParam,
2170 .Set_FrameType = MFC_Encoder_Set_FrameType,
2171 .Set_FrameRate = MFC_Encoder_Set_FrameRate,
2172 .Set_BitRate = MFC_Encoder_Set_BitRate,
2173 .Set_FrameSkip = MFC_Encoder_Set_FrameSkip,
2174 .Set_IDRPeriod = MFC_Encoder_Set_IDRPeriod,
2175 .Set_FrameTag = MFC_Encoder_Set_FrameTag,
2176 .Get_FrameTag = MFC_Encoder_Get_FrameTag,
2177 .Enable_PrependSpsPpsToIdr = MFC_Encoder_Enable_PrependSpsPpsToIdr,
2181 * [Encoder Buffer OPS] Input
2183 static ExynosVideoEncBufferOps defInbufOps = {
2185 .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Inbuf,
2186 .Set_Shareable = MFC_Encoder_Set_Shareable_Inbuf,
2187 .Get_Buffer = MFC_Encoder_Get_Buffer_Inbuf,
2188 .Set_Geometry = MFC_Encoder_Set_Geometry_Inbuf,
2189 .Get_Geometry = MFC_Encoder_Get_Geometry_Inbuf,
2190 .Setup = MFC_Encoder_Setup_Inbuf,
2191 .Run = MFC_Encoder_Run_Inbuf,
2192 .Stop = MFC_Encoder_Stop_Inbuf,
2193 .Enqueue = MFC_Encoder_Enqueue_Inbuf,
2194 .Enqueue_All = NULL,
2195 .Dequeue = MFC_Encoder_Dequeue_Inbuf,
2196 .Register = MFC_Encoder_Register_Inbuf,
2197 .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Inbuf,
2198 .Clear_Queue = MFC_Encoder_Clear_Queued_Inbuf,
2202 * [Encoder Buffer OPS] Output
2204 static ExynosVideoEncBufferOps defOutbufOps = {
2206 .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Outbuf,
2207 .Set_Shareable = MFC_Encoder_Set_Shareable_Outbuf,
2208 .Get_Buffer = MFC_Encoder_Get_Buffer_Outbuf,
2209 .Set_Geometry = MFC_Encoder_Set_Geometry_Outbuf,
2210 .Get_Geometry = MFC_Encoder_Get_Geometry_Outbuf,
2211 .Setup = MFC_Encoder_Setup_Outbuf,
2212 .Run = MFC_Encoder_Run_Outbuf,
2213 .Stop = MFC_Encoder_Stop_Outbuf,
2214 .Enqueue = MFC_Encoder_Enqueue_Outbuf,
2215 .Enqueue_All = NULL,
2216 .Dequeue = MFC_Encoder_Dequeue_Outbuf,
2217 .Register = MFC_Encoder_Register_Outbuf,
2218 .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Outbuf,
2219 .Clear_Queue = MFC_Encoder_Clear_Queued_Outbuf,
2222 int Exynos_Video_Register_Encoder(
2223 ExynosVideoEncOps *pEncOps,
2224 ExynosVideoEncBufferOps *pInbufOps,
2225 ExynosVideoEncBufferOps *pOutbufOps)
2227 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2229 if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
2230 ret = VIDEO_ERROR_BADPARAM;
2234 defEncOps.nSize = sizeof(defEncOps);
2235 defInbufOps.nSize = sizeof(defInbufOps);
2236 defOutbufOps.nSize = sizeof(defOutbufOps);
2238 memcpy((char *)pEncOps + sizeof(pEncOps->nSize), (char *)&defEncOps + sizeof(defEncOps.nSize),
2239 pEncOps->nSize - sizeof(pEncOps->nSize));
2241 memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
2242 pInbufOps->nSize - sizeof(pInbufOps->nSize));
2244 memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
2245 pOutbufOps->nSize - sizeof(pOutbufOps->nSize));