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 int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING);
139 pCtx = (ExynosVideoEncContext *)malloc(sizeof(*pCtx));
141 ALOGE("%s: Failed to allocate encoder context buffer", __func__);
142 goto EXIT_ALLOC_FAIL;
145 memset(pCtx, 0, sizeof(*pCtx));
147 pCtx->hEnc = exynos_v4l2_open_devname(VIDEO_ENCODER_NAME, O_RDWR, 0);
148 if (pCtx->hEnc < 0) {
149 ALOGE("%s: Failed to open encoder device", __func__);
153 if (!exynos_v4l2_querycap(pCtx->hEnc, needCaps)) {
154 ALOGE("%s: Failed to querycap", __func__);
155 goto EXIT_QUERYCAP_FAIL;
158 pCtx->bStreamonInbuf = VIDEO_FALSE;
159 pCtx->bStreamonOutbuf = VIDEO_FALSE;
161 pCtx->nMemoryType = nMemoryType;
163 pCtx->pInMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
164 if (pCtx->pInMutex == NULL) {
165 ALOGE("%s: Failed to allocate mutex about input buffer", __func__);
166 goto EXIT_QUERYCAP_FAIL;
168 if (pthread_mutex_init(pCtx->pInMutex, NULL) != 0) {
169 goto EXIT_QUERYCAP_FAIL;
172 pCtx->pOutMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
173 if (pCtx->pOutMutex == NULL) {
174 ALOGE("%s: Failed to allocate mutex about output buffer", __func__);
175 goto EXIT_QUERYCAP_FAIL;
177 if (pthread_mutex_init(pCtx->pOutMutex, NULL) != 0) {
178 goto EXIT_QUERYCAP_FAIL;
184 if (pCtx->pInMutex != NULL) {
185 pthread_mutex_destroy(pCtx->pInMutex);
186 free(pCtx->pInMutex);
189 if (pCtx->pOutMutex != NULL) {
190 pthread_mutex_destroy(pCtx->pOutMutex);
191 free(pCtx->pOutMutex);
204 * [Encoder OPS] Finalize
206 static ExynosVideoErrorType MFC_Encoder_Finalize(void *pHandle)
208 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
209 ExynosVideoPlane *pVideoPlane = NULL;
210 pthread_mutex_t *pMutex = NULL;
211 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
215 ALOGE("%s: Video context info must be supplied", __func__);
216 ret = VIDEO_ERROR_BADPARAM;
220 if (pCtx->pOutMutex != NULL) {
221 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
222 pthread_mutex_destroy(pMutex);
224 pCtx->pOutMutex = NULL;
227 if (pCtx->pInMutex != NULL) {
228 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
229 pthread_mutex_destroy(pMutex);
231 pCtx->pInMutex = NULL;
234 if (pCtx->bShareInbuf == VIDEO_FALSE) {
235 for (i = 0; i < pCtx->nInbufs; i++) {
236 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
237 pVideoPlane = &pCtx->pInbuf[i].planes[j];
238 if (pVideoPlane->addr != NULL) {
239 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
240 pVideoPlane->addr = NULL;
241 pVideoPlane->allocSize = 0;
242 pVideoPlane->dataSize = 0;
245 pCtx->pInbuf[i].pGeometry = NULL;
246 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
247 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
252 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
253 for (i = 0; i < pCtx->nOutbufs; i++) {
254 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
255 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
256 if (pVideoPlane->addr != NULL) {
257 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
258 pVideoPlane->addr = NULL;
259 pVideoPlane->allocSize = 0;
260 pVideoPlane->dataSize = 0;
263 pCtx->pOutbuf[i].pGeometry = NULL;
264 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
265 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
270 if (pCtx->pInbuf != NULL)
273 if (pCtx->pOutbuf != NULL)
286 * [Encoder OPS] Set Extended Control
288 static ExynosVideoErrorType MFC_Encoder_Set_EncParam (
290 ExynosVideoEncParam *pEncParam)
292 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
293 ExynosVideoEncInitParam *pInitParam = NULL;
294 ExynosVideoEncCommonParam *pCommonParam = NULL;
296 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
299 struct v4l2_ext_control ext_ctrl[MAX_CTRL_NUM];
300 struct v4l2_ext_controls ext_ctrls;
303 if ((pCtx == NULL) || (pEncParam == NULL)) {
304 ALOGE("%s: Video context info must be supplied", __func__);
305 ret = VIDEO_ERROR_BADPARAM;
309 pInitParam = &pEncParam->initParam;
310 pCommonParam = &pEncParam->commonParam;
312 /* common parameters */
313 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
314 ext_ctrl[k++].value = pCommonParam->IDRPeriod;
315 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
316 ext_ctrl[k++].value = pCommonParam->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */
317 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB;
318 ext_ctrl[k++].value = pCommonParam->RandomIntraMBRefresh;
319 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING;
320 ext_ctrl[k++].value = pCommonParam->PadControlOn;
321 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV;
322 ext_ctrl[k].value = pCommonParam->CrPadVal;
323 ext_ctrl[k].value |= (pCommonParam->CbPadVal << 8);
324 ext_ctrl[k++].value |= (pCommonParam->LumaPadVal << 16);
325 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
326 ext_ctrl[k++].value = pCommonParam->EnableFRMRateControl;
327 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
328 ext_ctrl[k++].value = pCommonParam->EnableMBRateControl;
329 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_BITRATE;
331 /* FIXME temporary fix */
332 if (pCommonParam->Bitrate)
333 ext_ctrl[k++].value = pCommonParam->Bitrate;
335 ext_ctrl[k++].value = 1; /* just for testing Movie studio */
337 /* codec specific parameters */
338 switch (pEncParam->eCompressionFormat) {
339 case VIDEO_CODING_AVC:
341 ExynosVideoEncH264Param *pH264Param = &pEncParam->codecParam.h264;
343 /* common parameters but id is depends on codec */
344 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
345 ext_ctrl[k++].value = pCommonParam->FrameQp;
346 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
347 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
348 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
349 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
350 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
351 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
352 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
353 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
355 /* H.264 specific parameters */
356 switch (pCommonParam->SliceMode) {
358 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
359 ext_ctrl[k++].value = 1; /* default */
360 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
361 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
364 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
365 ext_ctrl[k++].value = pH264Param->SliceArgument;
366 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
367 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
369 case 2: /* Fixed Byte number Slice mode */
370 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
371 ext_ctrl[k++].value = 1; /* default */
372 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
373 ext_ctrl[k++].value = pH264Param->SliceArgument;
379 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
380 ext_ctrl[k++].value = pH264Param->ProfileIDC;
381 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
382 ext_ctrl[k++].value = pH264Param->LevelIDC;
383 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P;
384 ext_ctrl[k++].value = pH264Param->NumberRefForPframes;
386 * It should be set using h264Param->NumberBFrames after being handled by appl.
388 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
389 ext_ctrl[k++].value = pH264Param->NumberBFrames;
390 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
391 ext_ctrl[k++].value = pH264Param->LoopFilterDisable;
392 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
393 ext_ctrl[k++].value = pH264Param->LoopFilterAlphaC0Offset;
394 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
395 ext_ctrl[k++].value = pH264Param->LoopFilterBetaOffset;
396 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
397 ext_ctrl[k++].value = pH264Param->SymbolMode;
398 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE
399 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE;
400 ext_ctrl[k++].value = pH264Param->PictureInterlace;
402 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM;
403 ext_ctrl[k++].value = pH264Param->Transform8x8Mode;
404 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE
405 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE;
406 ext_ctrl[k++].value = pH264Param->FrameRate;
408 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
409 ext_ctrl[k++].value = pH264Param->FrameQp_B;
411 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK;
412 ext_ctrl[k++].value = pH264Param->DarkDisable;
413 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH;
414 ext_ctrl[k++].value = pH264Param->SmoothDisable;
415 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC;
416 ext_ctrl[k++].value = pH264Param->StaticDisable;
417 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY;
418 ext_ctrl[k++].value = pH264Param->ActivityDisable;
420 /* doesn't have to be set */
421 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE;
422 ext_ctrl[k++].value = 1;
423 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD;
424 ext_ctrl[k++].value = 10;
425 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
426 ext_ctrl[k++].value = 0;
427 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
428 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; /* 0: seperated header, 1: header + first frame */
429 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE;
430 ext_ctrl[k++].value = 0;
431 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC;
432 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED;
433 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH;
434 ext_ctrl[k++].value = 0;
435 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT;
436 ext_ctrl[k++].value = 0;
438 /* Initial parameters : Frame Skip */
439 switch (pInitParam->FrameSkip) {
440 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
442 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
443 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
445 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
446 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
447 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
450 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
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_DISABLED;
456 /* SVC is not supported yet */
457 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING;
458 ext_ctrl[k++].value = 0;
459 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
460 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B;
461 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
462 ext_ctrl[k++].value = 3;
463 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
464 ext_ctrl[k++].value = (0 << 16 | 0);
465 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
466 ext_ctrl[k++].value = (1 << 16 | 0);
467 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
468 ext_ctrl[k++].value = (2 << 16 | 0);
469 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING;
470 ext_ctrl[k++].value = 0;
471 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0;
472 ext_ctrl[k++].value = 0;
473 #ifdef V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE
474 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE;
475 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE;
477 /* FMO is not supported yet */
478 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO;
479 ext_ctrl[k++].value = 0;
480 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE;
481 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES;
482 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP;
483 ext_ctrl[k++].value = 4;
484 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
485 ext_ctrl[k++].value = (0 << 30 | 0);
486 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
487 ext_ctrl[k++].value = (1 << 30 | 0);
488 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
489 ext_ctrl[k++].value = (2 << 30 | 0);
490 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
491 ext_ctrl[k++].value = (3 << 30 | 0);
492 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION;
493 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT;
494 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE;
495 ext_ctrl[k++].value = 0;
497 /* ASO is not supported yet */
498 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO;
499 ext_ctrl[k++].value = 0;
501 for (i = 0; i < 32; i++) {
502 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER;
503 ext_ctrl[k++].value = (i << 16 | 0);
506 ext_ctrls.count = H264_CTRL_NUM;
510 case VIDEO_CODING_MPEG4:
512 ExynosVideoEncMpeg4Param *pMpeg4Param = &pEncParam->codecParam.mpeg4;
514 /* common parameters but id is depends on codec */
515 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP;
516 ext_ctrl[k++].value = pCommonParam->FrameQp;
517 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP;
518 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
519 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP;
520 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
521 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP;
522 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
523 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
524 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
526 /* MPEG4 specific parameters */
527 switch (pCommonParam->SliceMode) {
529 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
530 ext_ctrl[k++].value = 1; /* default */
531 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
532 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
535 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
536 ext_ctrl[k++].value = pMpeg4Param->SliceArgument;
537 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
538 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
541 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
542 ext_ctrl[k++].value = 1; /* default */
543 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
544 ext_ctrl[k++].value = pMpeg4Param->SliceArgument;
550 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
551 ext_ctrl[k++].value = pMpeg4Param->ProfileIDC;
552 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
553 ext_ctrl[k++].value = pMpeg4Param->LevelIDC;
554 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL;
555 ext_ctrl[k++].value = pMpeg4Param->DisableQpelME;
558 * It should be set using mpeg4Param->NumberBFrames after being handled by appl.
560 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
561 ext_ctrl[k++].value = pMpeg4Param->NumberBFrames;
562 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES
563 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES;
564 ext_ctrl[k++].value = pMpeg4Param->TimeIncreamentRes;
566 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA
567 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA;
568 ext_ctrl[k++].value = pMpeg4Param->VopTimeIncreament;
570 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP;
571 ext_ctrl[k++].value = pMpeg4Param->FrameQp_B;
572 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
573 ext_ctrl[k++].value = 0;
574 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
575 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
576 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
577 ext_ctrl[k++].value = 1;
579 /* Initial parameters : Frame Skip */
580 switch (pInitParam->FrameSkip) {
581 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
582 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
583 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
585 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
586 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
587 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
590 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
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_DISABLED;
596 ext_ctrls.count = MPEG4_CTRL_NUM;
600 case VIDEO_CODING_H263:
602 ExynosVideoEncH263Param *pH263Param = &pEncParam->codecParam.h263;
604 /* common parameters but id is depends on codec */
605 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP;
606 ext_ctrl[k++].value = pCommonParam->FrameQp;
607 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP;
608 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
609 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP;
610 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
611 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP;
612 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
613 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
614 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
616 /* H263 specific parameters */
617 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE
618 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE;
619 ext_ctrl[k++].value = pH263Param->FrameRate;
621 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
622 ext_ctrl[k++].value = 0;
623 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
624 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
625 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
626 ext_ctrl[k++].value = 1;
628 /* Initial parameters : Frame Skip */
629 switch (pInitParam->FrameSkip) {
630 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
631 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
632 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
634 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
635 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
636 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
639 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
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_DISABLED;
644 ext_ctrls.count = H263_CTRL_NUM;
649 ALOGE("[%s] Undefined codec type",__func__);
650 ret = VIDEO_ERROR_BADPARAM;
654 ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
655 ext_ctrls.controls = ext_ctrl;
657 if (exynos_v4l2_s_ext_ctrl(pCtx->hEnc, &ext_ctrls) != 0) {
658 ALOGE("%s: Failed to s_ext_ctrl", __func__);
659 ret = VIDEO_ERROR_APIFAIL;
668 * [Encoder OPS] Set Frame Tag
670 static ExynosVideoErrorType MFC_Encoder_Set_FrameTag(
674 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
675 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
678 ALOGE("%s: Video context info must be supplied", __func__);
679 ret = VIDEO_ERROR_BADPARAM;
682 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
683 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) {
684 ALOGE("%s: Failed to s_ctrl", __func__);
685 ret = VIDEO_ERROR_APIFAIL;
694 * [Encoder OPS] Get Frame Tag
696 static int MFC_Encoder_Get_FrameTag(void *pHandle)
698 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
703 ALOGE("%s: Video context info must be supplied", __func__);
706 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
707 if (exynos_v4l2_g_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag) != 0) {
708 ALOGE("%s: Failed to g_ctrl", __func__);
717 * [Encoder OPS] Set Frame Type
719 static ExynosVideoErrorType MFC_Encoder_Set_FrameType(
721 ExynosVideoFrameType frameType)
723 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
724 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
727 ALOGE("%s: Video context info must be supplied", __func__);
728 ret = VIDEO_ERROR_BADPARAM;
733 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE, frameType) != 0) {
734 ALOGE("%s: Failed to s_ctrl", __func__);
735 ret = VIDEO_ERROR_APIFAIL;
745 * [Encoder OPS] Set Frame Rate
747 static ExynosVideoErrorType MFC_Encoder_Set_FrameRate(
751 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
752 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
755 ALOGE("%s: Video context info must be supplied", __func__);
756 ret = VIDEO_ERROR_BADPARAM;
759 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH
760 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH, frameRate) != 0) {
761 ALOGE("%s: Failed to s_ctrl", __func__);
762 ret = VIDEO_ERROR_APIFAIL;
772 * [Encoder OPS] Set Bit Rate
774 static ExynosVideoErrorType MFC_Encoder_Set_BitRate(
778 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
779 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
782 ALOGE("%s: Video context info must be supplied", __func__);
783 ret = VIDEO_ERROR_BADPARAM;
786 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH
787 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH, bitRate) != 0) {
788 ALOGE("%s: Failed to s_ctrl", __func__);
789 ret = VIDEO_ERROR_APIFAIL;
798 * [Encoder OPS] Set Frame Skip
800 static ExynosVideoErrorType MFC_Encoder_Set_FrameSkip(
804 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
805 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
808 ALOGE("%s: Video context info must be supplied", __func__);
809 ret = VIDEO_ERROR_BADPARAM;
813 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE, frameSkip) != 0) {
814 ALOGE("%s: Failed to s_ctrl", __func__);
815 ret = VIDEO_ERROR_APIFAIL;
824 * [Encoder OPS] Set IDR Period
826 static ExynosVideoErrorType MFC_Encoder_Set_IDRPeriod(
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_MPEG_VIDEO_H264_I_PERIOD, IDRPeriod) != 0) {
840 ALOGE("%s: Failed to s_ctrl", __func__);
841 ret = VIDEO_ERROR_APIFAIL;
850 * [Encoder OPS] Enable Prepend SPS and PPS to every IDR Frames
852 static ExynosVideoErrorType MFC_Encoder_Enable_PrependSpsPpsToIdr(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;
862 #ifdef V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR
863 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR, 1) != 0) {
864 ALOGE("%s: Failed to s_ctrl", __func__);
865 ret = VIDEO_ERROR_APIFAIL;
874 * [Encoder Buffer OPS] Enable Cacheable (Input)
876 static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_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;
886 #ifdef V4L2_CID_CACHEABLE
887 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 2) != 0) {
888 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__);
889 ret = VIDEO_ERROR_APIFAIL;
898 * [Encoder Buffer OPS] Enable Cacheable (Output)
900 static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Outbuf(void *pHandle)
902 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
903 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
906 ALOGE("%s: Video context info must be supplied", __func__);
907 ret = VIDEO_ERROR_BADPARAM;
910 #ifdef V4L2_CID_CACHEABLE
911 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 1) != 0) {
912 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__);
913 ret = VIDEO_ERROR_APIFAIL;
922 * [Encoder Buffer OPS] Set Shareable Buffer (Input)
924 static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Inbuf(void *pHandle)
926 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
927 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
930 ALOGE("%s: Video context info must be supplied", __func__);
931 ret = VIDEO_ERROR_BADPARAM;
935 pCtx->bShareInbuf = VIDEO_TRUE;
942 * [Encoder Buffer OPS] Set Shareable Buffer (Output)
944 static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Outbuf(void *pHandle)
946 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
947 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
950 ALOGE("%s: Video context info must be supplied", __func__);
951 ret = VIDEO_ERROR_BADPARAM;
955 pCtx->bShareOutbuf = VIDEO_TRUE;
962 * [Encoder Buffer OPS] Get Buffer (Input)
964 static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Inbuf(
967 ExynosVideoBuffer **pBuffer)
969 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
970 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
973 ALOGE("%s: Video context info must be supplied", __func__);
975 ret = VIDEO_ERROR_NOBUFFERS;
979 if (pCtx->nInbufs <= nIndex) {
981 ret = VIDEO_ERROR_BADPARAM;
985 *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex];
992 * [Encoder Buffer OPS] Get Buffer (Output)
994 static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Outbuf(
997 ExynosVideoBuffer **pBuffer)
999 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1000 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1003 ALOGE("%s: Video context info must be supplied", __func__);
1005 ret = VIDEO_ERROR_NOBUFFERS;
1009 if (pCtx->nOutbufs <= nIndex) {
1011 ret = VIDEO_ERROR_BADPARAM;
1015 *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex];
1022 * [Encoder Buffer OPS] Set Geometry (Src)
1024 static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Inbuf(
1026 ExynosVideoGeometry *bufferConf)
1028 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1029 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1031 struct v4l2_format fmt;
1034 ALOGE("%s: Video context info must be supplied", __func__);
1035 ret = VIDEO_ERROR_BADPARAM;
1039 if (bufferConf == NULL) {
1040 ALOGE("%s: Buffer geometry must be supplied", __func__);
1041 ret = VIDEO_ERROR_BADPARAM;
1045 memset(&fmt, 0, sizeof(fmt));
1047 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1048 fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat);
1049 fmt.fmt.pix_mp.width = bufferConf->nFrameWidth;
1050 fmt.fmt.pix_mp.height = bufferConf->nFrameHeight;
1051 fmt.fmt.pix_mp.num_planes = VIDEO_ENCODER_INBUF_PLANES;
1054 if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) {
1055 ALOGE("%s: Failed to s_fmt", __func__);
1056 ret = VIDEO_ERROR_APIFAIL;
1060 memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry));
1067 * [Encoder Buffer OPS] Get Geometry (Src)
1069 static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Inbuf(
1071 ExynosVideoGeometry *bufferConf)
1073 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1074 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1076 struct v4l2_format fmt;
1079 ALOGE("%s: Video context info must be supplied", __func__);
1080 ret = VIDEO_ERROR_BADPARAM;
1084 if (bufferConf == NULL) {
1085 ALOGE("%s: Buffer geometry must be supplied", __func__);
1086 ret = VIDEO_ERROR_BADPARAM;
1090 memset(&fmt, 0, sizeof(fmt));
1092 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1093 if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) {
1094 ALOGE("%s: Failed to g_fmt", __func__);
1095 ret = VIDEO_ERROR_APIFAIL;
1099 bufferConf->nFrameHeight = fmt.fmt.pix_mp.width;
1100 bufferConf->nFrameHeight = fmt.fmt.pix_mp.height;
1101 bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1108 * [Encoder Buffer OPS] Set Geometry (Dst)
1110 static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Outbuf(
1112 ExynosVideoGeometry *bufferConf)
1114 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1115 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1117 struct v4l2_format fmt;
1120 ALOGE("%s: Video context info must be supplied", __func__);
1121 ret = VIDEO_ERROR_BADPARAM;
1125 if (bufferConf == NULL) {
1126 ALOGE("%s: Buffer geometry must be supplied", __func__);
1127 ret = VIDEO_ERROR_BADPARAM;
1131 memset(&fmt, 0, sizeof(fmt));
1133 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1134 fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat);
1135 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage;
1137 if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) {
1138 ALOGE("%s: Failed to s_fmt", __func__);
1139 ret = VIDEO_ERROR_APIFAIL;
1143 memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry));
1150 * [Encoder Buffer OPS] Get Geometry (Dst)
1152 static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Outbuf(
1154 ExynosVideoGeometry *bufferConf)
1156 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1157 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1159 struct v4l2_format fmt;
1162 ALOGE("%s: Video context info must be supplied", __func__);
1163 ret = VIDEO_ERROR_BADPARAM;
1167 if (bufferConf == NULL) {
1168 ALOGE("%s: Buffer geometry must be supplied", __func__);
1169 ret = VIDEO_ERROR_BADPARAM;
1173 memset(&fmt, 0, sizeof(fmt));
1175 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1176 if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) {
1177 ALOGE("%s: Failed to g_fmt", __func__);
1178 ret = VIDEO_ERROR_APIFAIL;
1183 bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1190 * [Encoder Buffer OPS] Setup (Src)
1192 static ExynosVideoErrorType MFC_Encoder_Setup_Inbuf(
1194 unsigned int nBufferCount)
1196 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1197 ExynosVideoPlane *pVideoPlane = NULL;
1198 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1200 struct v4l2_requestbuffers req;
1201 struct v4l2_buffer buf;
1202 struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES];
1206 ALOGE("%s: Video context info must be supplied", __func__);
1207 ret = VIDEO_ERROR_BADPARAM;
1211 if (nBufferCount == 0) {
1212 ALOGE("%s: Buffer count must be greater than 0", __func__);
1213 ret = VIDEO_ERROR_BADPARAM;
1217 memset(&req, 0, sizeof(req));
1219 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1220 req.count = nBufferCount;
1222 if (pCtx->bShareInbuf == VIDEO_TRUE)
1223 req.memory = pCtx->nMemoryType;
1225 req.memory = V4L2_MEMORY_MMAP;
1227 if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) {
1228 ALOGE("Failed to require buffer");
1229 ret = VIDEO_ERROR_APIFAIL;
1233 pCtx->nInbufs = (int)req.count;
1235 pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
1236 if (pCtx->pInbuf == NULL) {
1237 ALOGE("%s: Failed to allocate input buffer context", __func__);
1238 ret = VIDEO_ERROR_NOMEM;
1241 memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
1243 memset(&buf, 0, sizeof(buf));
1245 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1246 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1247 buf.memory = V4L2_MEMORY_MMAP;
1248 buf.m.planes = planes;
1249 buf.length = VIDEO_ENCODER_INBUF_PLANES;
1251 for (i = 0; i < pCtx->nInbufs; i++) {
1253 if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) {
1254 ALOGE("%s: Failed to querybuf", __func__);
1255 ret = VIDEO_ERROR_APIFAIL;
1259 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
1260 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1261 pVideoPlane->addr = mmap(NULL,
1262 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1263 MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset);
1265 if (pVideoPlane->addr == MAP_FAILED) {
1266 ALOGE("%s: Failed to map", __func__);
1267 ret = VIDEO_ERROR_MAPFAIL;
1271 pVideoPlane->allocSize = buf.m.planes[j].length;
1272 pVideoPlane->dataSize = 0;
1275 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
1276 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1277 pCtx->pInbuf[i].bRegistered = VIDEO_TRUE;
1281 for (i = 0; i < pCtx->nInbufs; i++) {
1282 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
1283 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1284 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
1291 if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) {
1292 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1293 for (i = 0; i < pCtx->nInbufs; i++) {
1294 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
1295 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1296 if (pVideoPlane->addr == MAP_FAILED) {
1297 pVideoPlane->addr = NULL;
1301 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1313 * [Encoder Buffer OPS] Setup (Dst)
1315 static ExynosVideoErrorType MFC_Encoder_Setup_Outbuf(
1317 unsigned int nBufferCount)
1319 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1320 ExynosVideoPlane *pVideoPlane = NULL;
1321 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1323 struct v4l2_requestbuffers req;
1324 struct v4l2_buffer buf;
1325 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
1329 ALOGE("%s: Video context info must be supplied", __func__);
1330 ret = VIDEO_ERROR_BADPARAM;
1334 if (nBufferCount == 0) {
1335 ALOGE("%s: Buffer count must be greater than 0", __func__);
1336 ret = VIDEO_ERROR_BADPARAM;
1340 memset(&req, 0, sizeof(req));
1342 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1343 req.count = nBufferCount;
1345 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1346 req.memory = pCtx->nMemoryType;
1348 req.memory = V4L2_MEMORY_MMAP;
1350 if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) {
1351 ALOGE("%s: Failed to reqbuf", __func__);
1352 ret = VIDEO_ERROR_APIFAIL;
1356 pCtx->nOutbufs = req.count;
1358 pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1359 if (pCtx->pOutbuf == NULL) {
1360 ALOGE("%s: Failed to allocate output buffer context", __func__);
1361 ret = VIDEO_ERROR_NOMEM;
1364 memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1366 memset(&buf, 0, sizeof(buf));
1368 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1369 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1370 buf.memory = V4L2_MEMORY_MMAP;
1371 buf.m.planes = planes;
1372 buf.length = VIDEO_ENCODER_OUTBUF_PLANES;
1374 for (i = 0; i < pCtx->nOutbufs; i++) {
1376 if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) {
1377 ALOGE("%s: Failed to querybuf", __func__);
1378 ret = VIDEO_ERROR_APIFAIL;
1382 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
1383 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1384 pVideoPlane->addr = mmap(NULL,
1385 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1386 MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset);
1388 if (pVideoPlane->addr == MAP_FAILED) {
1389 ALOGE("%s: Failed to map", __func__);
1390 ret = VIDEO_ERROR_MAPFAIL;
1394 pVideoPlane->allocSize = buf.m.planes[j].length;
1395 pVideoPlane->dataSize = 0;
1398 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1399 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1400 pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE;
1403 for (i = 0; i < pCtx->nOutbufs; i++ ) {
1404 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1405 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1406 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
1413 if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) {
1414 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1415 for (i = 0; i < pCtx->nOutbufs; i++) {
1416 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
1417 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1418 if (pVideoPlane->addr == MAP_FAILED) {
1419 pVideoPlane->addr = NULL;
1423 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1428 free(pCtx->pOutbuf);
1435 * [Encoder Buffer OPS] Run (src)
1437 static ExynosVideoErrorType MFC_Encoder_Run_Inbuf(void *pHandle)
1439 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1440 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1443 ALOGE("%s: Video context info must be supplied", __func__);
1444 ret = VIDEO_ERROR_BADPARAM;
1448 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1449 if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1450 ALOGE("%s: Failed to streamon for input buffer", __func__);
1451 ret = VIDEO_ERROR_APIFAIL;
1454 pCtx->bStreamonInbuf = VIDEO_TRUE;
1462 * [Encoder Buffer OPS] Run (Dst)
1464 static ExynosVideoErrorType MFC_Encoder_Run_Outbuf(void *pHandle)
1466 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1467 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1470 ALOGE("%s: Video context info must be supplied", __func__);
1471 ret = VIDEO_ERROR_BADPARAM;
1475 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1476 if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1477 ALOGE("%s: Failed to streamon for output buffer", __func__);
1478 ret = VIDEO_ERROR_APIFAIL;
1481 pCtx->bStreamonOutbuf = VIDEO_TRUE;
1489 * [Encoder Buffer OPS] Stop (Src)
1491 static ExynosVideoErrorType MFC_Encoder_Stop_Inbuf(void *pHandle)
1493 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1494 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1498 ALOGE("%s: Video context info must be supplied", __func__);
1499 ret = VIDEO_ERROR_BADPARAM;
1503 if (pCtx->bStreamonInbuf == VIDEO_TRUE) {
1504 if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1505 ALOGE("%s: Failed to streamoff for input buffer", __func__);
1506 ret = VIDEO_ERROR_APIFAIL;
1509 pCtx->bStreamonInbuf = VIDEO_FALSE;
1512 for (i = 0; i < pCtx->nInbufs; i++) {
1513 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1521 * [Encoder Buffer OPS] Stop (Dst)
1523 static ExynosVideoErrorType MFC_Encoder_Stop_Outbuf(void *pHandle)
1525 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1526 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1530 ALOGE("%s: Video context info must be supplied", __func__);
1531 ret = VIDEO_ERROR_BADPARAM;
1535 if (pCtx->bStreamonOutbuf == VIDEO_TRUE) {
1536 if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1537 ALOGE("%s: Failed to streamoff for output buffer", __func__);
1538 ret = VIDEO_ERROR_APIFAIL;
1541 pCtx->bStreamonOutbuf = VIDEO_FALSE;
1544 for (i = 0; i < pCtx->nOutbufs; i++) {
1545 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1554 * [Encoder Buffer OPS] Wait (Src)
1556 static ExynosVideoErrorType MFC_Encoder_Wait_Inbuf(void *pHandle)
1558 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1559 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1561 struct pollfd poll_events;
1565 ALOGE("%s: Video context info must be supplied", __func__);
1566 ret = VIDEO_ERROR_BADPARAM;
1570 poll_events.fd = pCtx->hEnc;
1571 poll_events.events = POLLOUT | POLLERR;
1572 poll_events.revents = 0;
1575 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
1576 if (poll_state > 0) {
1577 if (poll_events.revents & POLLOUT) {
1580 ALOGE("%s: Poll return error", __func__);
1581 ret = VIDEO_ERROR_POLL;
1584 } else if (poll_state < 0) {
1585 ALOGE("%s: Poll state error", __func__);
1586 ret = VIDEO_ERROR_POLL;
1589 } while (poll_state == 0);
1596 * [Encoder Buffer OPS] Wait (Dst)
1598 static ExynosVideoErrorType MFC_Encoder_Wait_Outbuf(void *pHandle)
1600 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1601 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1603 struct pollfd poll_events;
1605 int bframe_count = 0; // FIXME
1608 ALOGE("%s: Video context info must be supplied", __func__);
1609 ret = VIDEO_ERROR_BADPARAM;
1613 poll_events.fd = pCtx->hEnc;
1614 poll_events.events = POLLIN | POLLERR;
1615 poll_events.revents = 0;
1618 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
1619 if (poll_state > 0) {
1620 if (poll_events.revents & POLLIN) {
1623 ALOGE("%s: Poll return error", __func__);
1624 ret = VIDEO_ERROR_POLL;
1627 } else if (poll_state < 0) {
1628 ALOGE("%s: Poll state error", __func__);
1629 ret = VIDEO_ERROR_POLL;
1632 bframe_count++; // FIXME
1634 } while (poll_state == 0 && bframe_count < 5); // FIXME
1641 static ExynosVideoErrorType MFC_Encoder_Register_Inbuf(
1643 ExynosVideoPlane *planes,
1646 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1647 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1650 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_INBUF_PLANES)) {
1651 ALOGE("%s: input params must be supplied", __func__);
1652 ret = VIDEO_ERROR_BADPARAM;
1656 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1657 if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) {
1659 for (plane = 0; plane < nPlanes; plane++) {
1660 pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr;
1661 pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1662 pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd;
1663 ALOGV("%s: addr = 0x%x", __func__, pCtx->pInbuf[nIndex].planes[plane].addr);
1665 pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE;
1670 if (nIndex == pCtx->nInbufs) {
1671 ALOGE("%s: can not find non-registered input buffer", __func__);
1672 ret = VIDEO_ERROR_NOBUFFERS;
1679 static ExynosVideoErrorType MFC_Encoder_Register_Outbuf(
1681 ExynosVideoPlane *planes,
1684 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1685 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1688 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_OUTBUF_PLANES)) {
1689 ALOGE("%s: params must be supplied", __func__);
1690 ret = VIDEO_ERROR_BADPARAM;
1694 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1695 if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) {
1697 for (plane = 0; plane < nPlanes; plane++) {
1698 pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr;
1699 pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1700 pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd;
1702 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE;
1707 if (nIndex == pCtx->nOutbufs) {
1708 ALOGE("%s: can not find non-registered output buffer", __func__);
1709 ret = VIDEO_ERROR_NOBUFFERS;
1716 static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
1718 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1719 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1723 ALOGE("%s: Video context info must be supplied", __func__);
1724 ret = VIDEO_ERROR_BADPARAM;
1728 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1729 pCtx->pInbuf[nIndex].planes[0].addr = NULL;
1730 pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE;
1737 static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
1739 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1740 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1744 ALOGE("%s: Video context info must be supplied", __func__);
1745 ret = VIDEO_ERROR_BADPARAM;
1749 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1750 pCtx->pOutbuf[nIndex].planes[0].addr = NULL;
1751 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE;
1759 * [Encoder Buffer OPS] Find (Input)
1761 static int MFC_Encoder_Find_Inbuf(
1763 unsigned char *pBuffer)
1765 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1769 ALOGE("%s: Video context info must be supplied", __func__);
1773 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1774 if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) {
1775 if ((pBuffer == NULL) ||
1776 (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer))
1781 if (nIndex == pCtx->nInbufs)
1789 * [Encoder Buffer OPS] Find (Output)
1791 static int MFC_Encoder_Find_Outbuf(
1793 unsigned char *pBuffer)
1795 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1799 ALOGE("%s: Video context info must be supplied", __func__);
1803 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1804 if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) {
1805 if ((pBuffer == NULL) ||
1806 (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer))
1811 if (nIndex == pCtx->nOutbufs)
1819 * [Encoder Buffer OPS] Enqueue (Input)
1821 static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf(
1823 unsigned char *pBuffer[],
1824 unsigned int dataSize[],
1828 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1829 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1830 pthread_mutex_t *pMutex = NULL;
1832 struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES];
1833 struct v4l2_buffer buf;
1837 ALOGE("%s: Video context info must be supplied", __func__);
1838 ret = VIDEO_ERROR_BADPARAM;
1842 if (VIDEO_ENCODER_INBUF_PLANES < nPlanes) {
1843 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1844 VIDEO_ENCODER_INBUF_PLANES, nPlanes);
1845 ret = VIDEO_ERROR_BADPARAM;
1849 memset(&planes,0,sizeof(planes));
1850 memset(&buf, 0, sizeof(buf));
1852 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1853 buf.m.planes = planes;
1854 buf.length = VIDEO_ENCODER_INBUF_PLANES;
1856 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
1857 pthread_mutex_lock(pMutex);
1858 index = MFC_Encoder_Find_Inbuf(pCtx, pBuffer[0]);
1860 pthread_mutex_unlock(pMutex);
1861 ALOGE("%s: Failed to get index", __func__);
1862 ret = VIDEO_ERROR_NOBUFFERS;
1867 pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE;
1868 pthread_mutex_unlock(pMutex);
1870 if (pCtx->bShareInbuf == VIDEO_TRUE) {
1871 buf.memory = pCtx->nMemoryType;
1873 for (i = 0; i < nPlanes; i++) {
1874 /* V4L2_MEMORY_USERPTR */
1875 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1876 buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize;
1877 /* V4L2_MEMORY_DMABUF */
1878 #ifdef TIZEN_FEATURE_E3250 /* #ifdef USE_DMA_BUF */
1879 buf.m.planes[i].m.fd = pCtx->pInbuf[buf.index].planes[i].fd;
1880 buf.m.planes[i].length = 0; /* kernel give the length */
1882 buf.m.planes[i].bytesused = dataSize[i];
1885 buf.memory = V4L2_MEMORY_MMAP;
1886 for (i = 0; i < nPlanes; i++)
1887 buf.m.planes[i].bytesused = dataSize[i];
1890 ALOGE("call exynos_v4l2_qbuf(): %d", buf.m.planes[0].m.fd);
1891 if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) {
1892 ALOGE("%s: Failed to enqueue input buffer", __func__);
1893 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1894 ret = VIDEO_ERROR_APIFAIL;
1898 pCtx->pInbuf[buf.index].pPrivate = pPrivate;
1905 * [Encoder Buffer OPS] Enqueue (Output)
1907 static ExynosVideoErrorType MFC_Encoder_Enqueue_Outbuf(
1909 unsigned char *pBuffer[],
1910 unsigned int dataSize[],
1914 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1915 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1916 pthread_mutex_t *pMutex = NULL;
1918 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
1919 struct v4l2_buffer buf;
1923 ALOGE("%s: Video context info must be supplied", __func__);
1924 ret = VIDEO_ERROR_BADPARAM;
1928 if (VIDEO_ENCODER_OUTBUF_PLANES < nPlanes) {
1929 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1930 VIDEO_ENCODER_OUTBUF_PLANES, nPlanes);
1931 ret = VIDEO_ERROR_BADPARAM;
1935 memset(&buf, 0, sizeof(buf));
1937 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1938 buf.m.planes = planes;
1939 buf.length = VIDEO_ENCODER_OUTBUF_PLANES;
1941 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
1942 pthread_mutex_lock(pMutex);
1943 index = MFC_Encoder_Find_Outbuf(pCtx, pBuffer[0]);
1945 pthread_mutex_unlock(pMutex);
1946 ALOGE("%s: Failed to get index", __func__);
1947 ret = VIDEO_ERROR_NOBUFFERS;
1951 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE;
1952 pthread_mutex_unlock(pMutex);
1954 if (pCtx->bShareOutbuf == VIDEO_TRUE) {
1955 buf.memory = pCtx->nMemoryType;
1956 for (i = 0; i < nPlanes; i++) {
1957 /* V4L2_MEMORY_USERPTR */
1958 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1959 buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize;
1960 /* V4L2_MEMORY_DMABUF */
1962 buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd;
1963 buf.m.planes[i].length = 0; /* kernel give the length */
1965 buf.m.planes[i].bytesused = dataSize[i];
1968 buf.memory = V4L2_MEMORY_MMAP;
1971 if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) {
1972 ALOGE("%s: Failed to enqueue output buffer", __func__);
1973 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE;
1974 ret = VIDEO_ERROR_APIFAIL;
1978 pCtx->pOutbuf[buf.index].pPrivate = pPrivate;
1986 * [Encoder Buffer OPS] Enqueue All (Output)
1988 static ExynosVideoErrorType MFC_Encoder_Enqueue_All_Outbuf(void *pHandle)
1990 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1991 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1993 unsigned char *pBuffer[VIDEO_BUFFER_MAX_PLANES] = {NULL, };
1994 unsigned int dataSize[VIDEO_BUFFER_MAX_PLANES] = {0, };
1999 ALOGE("%s: Video context info must be supplied", __func__);
2000 ret = VIDEO_ERROR_BADPARAM;
2004 for (i = 0; i < pCtx->nOutbufs; i++) {
2005 ret = MFC_Encoder_Enqueue_Outbuf(pCtx, pBuffer, dataSize, 1, NULL);
2006 if (ret != VIDEO_ERROR_NONE)
2016 * [Encoder Buffer OPS] Dequeue (Input)
2018 static ExynosVideoBuffer *MFC_Encoder_Dequeue_Inbuf(void *pHandle)
2020 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2021 ExynosVideoBuffer *pInbuf = NULL;
2023 struct v4l2_buffer buf;
2026 ALOGE("%s: Video context info must be supplied", __func__);
2030 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
2035 memset(&buf, 0, sizeof(buf));
2037 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2039 if (pCtx->bShareInbuf == VIDEO_TRUE)
2040 buf.memory = pCtx->nMemoryType;
2042 buf.memory = V4L2_MEMORY_MMAP;
2044 if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) {
2049 pInbuf = &pCtx->pInbuf[buf.index];
2050 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
2057 * [Encoder Buffer OPS] Dequeue (Output)
2059 static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle)
2061 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2062 ExynosVideoBuffer *pOutbuf = NULL;
2064 struct v4l2_buffer buf;
2065 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
2068 ALOGE("%s: Video context info must be supplied", __func__);
2072 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
2077 memset(&buf, 0, sizeof(buf));
2079 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2080 buf.m.planes = planes;
2083 if (pCtx->bShareOutbuf == VIDEO_TRUE)
2084 buf.memory = pCtx->nMemoryType;
2086 buf.memory = V4L2_MEMORY_MMAP;
2088 /* no error case for output buffer dequeue in encoder */
2089 if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) {
2093 pOutbuf = &pCtx->pOutbuf[buf.index];
2094 pOutbuf->planes[0].dataSize = buf.m.planes[0].bytesused;
2096 switch (buf.flags & (0x7 << 3)) {
2097 case V4L2_BUF_FLAG_KEYFRAME:
2098 pOutbuf->frameType = VIDEO_FRAME_I;
2100 case V4L2_BUF_FLAG_PFRAME:
2101 pOutbuf->frameType = VIDEO_FRAME_P;
2103 case V4L2_BUF_FLAG_BFRAME:
2104 pOutbuf->frameType = VIDEO_FRAME_B;
2107 ALOGI("%s: encoded frame type is = %d",__func__, (buf.flags & (0x7 << 3)));
2108 pOutbuf->frameType = VIDEO_FRAME_OTHERS;
2112 pOutbuf->bQueued = VIDEO_FALSE;
2118 static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Inbuf(void *pHandle)
2120 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2121 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2125 ALOGE("%s: Video context info must be supplied", __func__);
2126 ret = VIDEO_ERROR_BADPARAM;
2130 for (i = 0; i < pCtx->nInbufs; i++) {
2131 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
2138 static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Outbuf(void *pHandle)
2140 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2141 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2145 ALOGE("%s: Video context info must be supplied", __func__);
2146 ret = VIDEO_ERROR_BADPARAM;
2150 for (i = 0; i < pCtx->nOutbufs; i++) {
2151 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
2159 * [Encoder OPS] Common
2161 static ExynosVideoEncOps defEncOps = {
2163 .Init = MFC_Encoder_Init,
2164 .Finalize = MFC_Encoder_Finalize,
2165 .Set_EncParam = MFC_Encoder_Set_EncParam,
2166 .Set_FrameType = MFC_Encoder_Set_FrameType,
2167 .Set_FrameRate = MFC_Encoder_Set_FrameRate,
2168 .Set_BitRate = MFC_Encoder_Set_BitRate,
2169 .Set_FrameSkip = MFC_Encoder_Set_FrameSkip,
2170 .Set_IDRPeriod = MFC_Encoder_Set_IDRPeriod,
2171 .Set_FrameTag = MFC_Encoder_Set_FrameTag,
2172 .Get_FrameTag = MFC_Encoder_Get_FrameTag,
2173 .Enable_PrependSpsPpsToIdr = MFC_Encoder_Enable_PrependSpsPpsToIdr,
2177 * [Encoder Buffer OPS] Input
2179 static ExynosVideoEncBufferOps defInbufOps = {
2181 .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Inbuf,
2182 .Set_Shareable = MFC_Encoder_Set_Shareable_Inbuf,
2183 .Get_Buffer = MFC_Encoder_Get_Buffer_Inbuf,
2184 .Set_Geometry = MFC_Encoder_Set_Geometry_Inbuf,
2185 .Get_Geometry = MFC_Encoder_Get_Geometry_Inbuf,
2186 .Setup = MFC_Encoder_Setup_Inbuf,
2187 .Run = MFC_Encoder_Run_Inbuf,
2188 .Stop = MFC_Encoder_Stop_Inbuf,
2189 .Enqueue = MFC_Encoder_Enqueue_Inbuf,
2190 .Enqueue_All = NULL,
2191 .Dequeue = MFC_Encoder_Dequeue_Inbuf,
2192 .Register = MFC_Encoder_Register_Inbuf,
2193 .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Inbuf,
2194 .Clear_Queue = MFC_Encoder_Clear_Queued_Inbuf,
2198 * [Encoder Buffer OPS] Output
2200 static ExynosVideoEncBufferOps defOutbufOps = {
2202 .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Outbuf,
2203 .Set_Shareable = MFC_Encoder_Set_Shareable_Outbuf,
2204 .Get_Buffer = MFC_Encoder_Get_Buffer_Outbuf,
2205 .Set_Geometry = MFC_Encoder_Set_Geometry_Outbuf,
2206 .Get_Geometry = MFC_Encoder_Get_Geometry_Outbuf,
2207 .Setup = MFC_Encoder_Setup_Outbuf,
2208 .Run = MFC_Encoder_Run_Outbuf,
2209 .Stop = MFC_Encoder_Stop_Outbuf,
2210 .Enqueue = MFC_Encoder_Enqueue_Outbuf,
2211 .Enqueue_All = NULL,
2212 .Dequeue = MFC_Encoder_Dequeue_Outbuf,
2213 .Register = MFC_Encoder_Register_Outbuf,
2214 .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Outbuf,
2215 .Clear_Queue = MFC_Encoder_Clear_Queued_Outbuf,
2218 int Exynos_Video_Register_Encoder(
2219 ExynosVideoEncOps *pEncOps,
2220 ExynosVideoEncBufferOps *pInbufOps,
2221 ExynosVideoEncBufferOps *pOutbufOps)
2223 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2225 if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
2226 ret = VIDEO_ERROR_BADPARAM;
2230 defEncOps.nSize = sizeof(defEncOps);
2231 defInbufOps.nSize = sizeof(defInbufOps);
2232 defOutbufOps.nSize = sizeof(defOutbufOps);
2234 memcpy((char *)pEncOps + sizeof(pEncOps->nSize), (char *)&defEncOps + sizeof(defEncOps.nSize),
2235 pEncOps->nSize - sizeof(pEncOps->nSize));
2237 memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
2238 pInbufOps->nSize - sizeof(pInbufOps->nSize));
2240 memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
2241 pOutbufOps->nSize - sizeof(pOutbufOps->nSize));