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 pCtx->pInMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
165 if (pCtx->pInMutex == NULL) {
166 ALOGE("%s: Failed to allocate mutex about input buffer", __func__);
167 goto EXIT_QUERYCAP_FAIL;
169 if (pthread_mutex_init(pCtx->pInMutex, NULL) != 0) {
170 goto EXIT_QUERYCAP_FAIL;
173 pCtx->pOutMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
174 if (pCtx->pOutMutex == NULL) {
175 ALOGE("%s: Failed to allocate mutex about output buffer", __func__);
176 goto EXIT_QUERYCAP_FAIL;
178 if (pthread_mutex_init(pCtx->pOutMutex, NULL) != 0) {
179 goto EXIT_QUERYCAP_FAIL;
185 if (pCtx->pInMutex != NULL) {
186 pthread_mutex_destroy(pCtx->pInMutex);
187 free(pCtx->pInMutex);
190 if (pCtx->pOutMutex != NULL) {
191 pthread_mutex_destroy(pCtx->pOutMutex);
192 free(pCtx->pOutMutex);
205 * [Encoder OPS] Finalize
207 static ExynosVideoErrorType MFC_Encoder_Finalize(void *pHandle)
209 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
210 ExynosVideoPlane *pVideoPlane = NULL;
211 pthread_mutex_t *pMutex = NULL;
212 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
216 ALOGE("%s: Video context info must be supplied", __func__);
217 ret = VIDEO_ERROR_BADPARAM;
221 if (pCtx->pOutMutex != NULL) {
222 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
223 pthread_mutex_destroy(pMutex);
225 pCtx->pOutMutex = NULL;
228 if (pCtx->pInMutex != NULL) {
229 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
230 pthread_mutex_destroy(pMutex);
232 pCtx->pInMutex = NULL;
235 if (pCtx->bShareInbuf == VIDEO_FALSE) {
236 for (i = 0; i < pCtx->nInbufs; i++) {
237 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
238 pVideoPlane = &pCtx->pInbuf[i].planes[j];
239 if (pVideoPlane->addr != NULL) {
240 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
241 pVideoPlane->addr = NULL;
242 pVideoPlane->allocSize = 0;
243 pVideoPlane->dataSize = 0;
246 pCtx->pInbuf[i].pGeometry = NULL;
247 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
248 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
253 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
254 for (i = 0; i < pCtx->nOutbufs; i++) {
255 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
256 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
257 if (pVideoPlane->addr != NULL) {
258 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
259 pVideoPlane->addr = NULL;
260 pVideoPlane->allocSize = 0;
261 pVideoPlane->dataSize = 0;
264 pCtx->pOutbuf[i].pGeometry = NULL;
265 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
266 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
271 if (pCtx->pInbuf != NULL)
274 if (pCtx->pOutbuf != NULL)
287 * [Encoder OPS] Set Extended Control
289 static ExynosVideoErrorType MFC_Encoder_Set_EncParam (
291 ExynosVideoEncParam *pEncParam)
293 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
294 ExynosVideoEncInitParam *pInitParam = NULL;
295 ExynosVideoEncCommonParam *pCommonParam = NULL;
297 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
300 struct v4l2_ext_control ext_ctrl[MAX_CTRL_NUM];
301 struct v4l2_ext_controls ext_ctrls;
304 if ((pCtx == NULL) || (pEncParam == NULL)) {
305 ALOGE("%s: Video context info must be supplied", __func__);
306 ret = VIDEO_ERROR_BADPARAM;
310 pInitParam = &pEncParam->initParam;
311 pCommonParam = &pEncParam->commonParam;
313 /* common parameters */
314 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
315 ext_ctrl[k++].value = pCommonParam->IDRPeriod;
316 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
317 ext_ctrl[k++].value = pCommonParam->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */
318 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB;
319 ext_ctrl[k++].value = pCommonParam->RandomIntraMBRefresh;
320 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING;
321 ext_ctrl[k++].value = pCommonParam->PadControlOn;
322 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV;
323 ext_ctrl[k].value = pCommonParam->CrPadVal;
324 ext_ctrl[k].value |= (pCommonParam->CbPadVal << 8);
325 ext_ctrl[k++].value |= (pCommonParam->LumaPadVal << 16);
326 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
327 ext_ctrl[k++].value = pCommonParam->EnableFRMRateControl;
328 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
329 ext_ctrl[k++].value = pCommonParam->EnableMBRateControl;
330 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_BITRATE;
332 /* FIXME temporary fix */
333 if (pCommonParam->Bitrate)
334 ext_ctrl[k++].value = pCommonParam->Bitrate;
336 ext_ctrl[k++].value = 1; /* just for testing Movie studio */
338 /* codec specific parameters */
339 switch (pEncParam->eCompressionFormat) {
340 case VIDEO_CODING_AVC:
342 ExynosVideoEncH264Param *pH264Param = &pEncParam->codecParam.h264;
344 /* common parameters but id is depends on codec */
345 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
346 ext_ctrl[k++].value = pCommonParam->FrameQp;
347 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
348 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
349 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
350 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
351 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
352 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
353 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
354 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
356 /* H.264 specific parameters */
357 switch (pCommonParam->SliceMode) {
359 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
360 ext_ctrl[k++].value = 1; /* default */
361 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
362 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
365 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
366 ext_ctrl[k++].value = pH264Param->SliceArgument;
367 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
368 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
370 case 2: /* Fixed Byte number Slice mode */
371 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
372 ext_ctrl[k++].value = 1; /* default */
373 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
374 ext_ctrl[k++].value = pH264Param->SliceArgument;
380 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
381 ext_ctrl[k++].value = pH264Param->ProfileIDC;
382 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
383 ext_ctrl[k++].value = pH264Param->LevelIDC;
384 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P;
385 ext_ctrl[k++].value = pH264Param->NumberRefForPframes;
387 * It should be set using h264Param->NumberBFrames after being handled by appl.
389 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
390 ext_ctrl[k++].value = pH264Param->NumberBFrames;
391 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
392 ext_ctrl[k++].value = pH264Param->LoopFilterDisable;
393 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
394 ext_ctrl[k++].value = pH264Param->LoopFilterAlphaC0Offset;
395 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
396 ext_ctrl[k++].value = pH264Param->LoopFilterBetaOffset;
397 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
398 ext_ctrl[k++].value = pH264Param->SymbolMode;
399 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE
400 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE;
401 ext_ctrl[k++].value = pH264Param->PictureInterlace;
403 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM;
404 ext_ctrl[k++].value = pH264Param->Transform8x8Mode;
405 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE
406 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE;
407 ext_ctrl[k++].value = pH264Param->FrameRate;
409 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
410 ext_ctrl[k++].value = pH264Param->FrameQp_B;
412 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK;
413 ext_ctrl[k++].value = pH264Param->DarkDisable;
414 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH;
415 ext_ctrl[k++].value = pH264Param->SmoothDisable;
416 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC;
417 ext_ctrl[k++].value = pH264Param->StaticDisable;
418 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY;
419 ext_ctrl[k++].value = pH264Param->ActivityDisable;
421 /* doesn't have to be set */
422 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE;
423 ext_ctrl[k++].value = 1;
424 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD;
425 ext_ctrl[k++].value = 10;
426 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
427 ext_ctrl[k++].value = 0;
428 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
429 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; /* 0: seperated header, 1: header + first frame */
430 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE;
431 ext_ctrl[k++].value = 0;
432 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC;
433 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED;
434 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH;
435 ext_ctrl[k++].value = 0;
436 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT;
437 ext_ctrl[k++].value = 0;
439 /* Initial parameters : Frame Skip */
440 switch (pInitParam->FrameSkip) {
441 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
443 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
444 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
446 case VIDEO_FRAME_SKIP_MODE_BUF_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_BUF_LIMIT;
451 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
452 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
453 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
457 /* SVC is not supported yet */
458 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING;
459 ext_ctrl[k++].value = 0;
460 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
461 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B;
462 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
463 ext_ctrl[k++].value = 3;
464 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
465 ext_ctrl[k++].value = (0 << 16 | 0);
466 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
467 ext_ctrl[k++].value = (1 << 16 | 0);
468 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
469 ext_ctrl[k++].value = (2 << 16 | 0);
470 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING;
471 ext_ctrl[k++].value = 0;
472 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0;
473 ext_ctrl[k++].value = 0;
474 #ifdef V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE
475 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE;
476 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE;
478 /* FMO is not supported yet */
479 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO;
480 ext_ctrl[k++].value = 0;
481 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE;
482 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES;
483 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP;
484 ext_ctrl[k++].value = 4;
485 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
486 ext_ctrl[k++].value = (0 << 30 | 0);
487 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
488 ext_ctrl[k++].value = (1 << 30 | 0);
489 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
490 ext_ctrl[k++].value = (2 << 30 | 0);
491 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
492 ext_ctrl[k++].value = (3 << 30 | 0);
493 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION;
494 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT;
495 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE;
496 ext_ctrl[k++].value = 0;
498 /* ASO is not supported yet */
499 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO;
500 ext_ctrl[k++].value = 0;
502 for (i = 0; i < 32; i++) {
503 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER;
504 ext_ctrl[k++].value = (i << 16 | 0);
507 ext_ctrls.count = H264_CTRL_NUM;
511 case VIDEO_CODING_MPEG4:
513 ExynosVideoEncMpeg4Param *pMpeg4Param = &pEncParam->codecParam.mpeg4;
515 /* common parameters but id is depends on codec */
516 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP;
517 ext_ctrl[k++].value = pCommonParam->FrameQp;
518 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP;
519 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
520 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP;
521 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
522 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP;
523 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
524 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
525 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
527 /* MPEG4 specific parameters */
528 switch (pCommonParam->SliceMode) {
530 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
531 ext_ctrl[k++].value = 1; /* default */
532 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
533 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
536 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
537 ext_ctrl[k++].value = pMpeg4Param->SliceArgument;
538 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
539 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
542 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
543 ext_ctrl[k++].value = 1; /* default */
544 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
545 ext_ctrl[k++].value = pMpeg4Param->SliceArgument;
551 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
552 ext_ctrl[k++].value = pMpeg4Param->ProfileIDC;
553 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
554 ext_ctrl[k++].value = pMpeg4Param->LevelIDC;
555 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL;
556 ext_ctrl[k++].value = pMpeg4Param->DisableQpelME;
559 * It should be set using mpeg4Param->NumberBFrames after being handled by appl.
561 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
562 ext_ctrl[k++].value = pMpeg4Param->NumberBFrames;
563 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES
564 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES;
565 ext_ctrl[k++].value = pMpeg4Param->TimeIncreamentRes;
567 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA
568 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA;
569 ext_ctrl[k++].value = pMpeg4Param->VopTimeIncreament;
571 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP;
572 ext_ctrl[k++].value = pMpeg4Param->FrameQp_B;
573 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
574 ext_ctrl[k++].value = 0;
575 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
576 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
577 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
578 ext_ctrl[k++].value = 1;
580 /* Initial parameters : Frame Skip */
581 switch (pInitParam->FrameSkip) {
582 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
583 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
584 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
586 case VIDEO_FRAME_SKIP_MODE_BUF_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_BUF_LIMIT;
591 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
592 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
593 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
597 ext_ctrls.count = MPEG4_CTRL_NUM;
601 case VIDEO_CODING_H263:
603 ExynosVideoEncH263Param *pH263Param = &pEncParam->codecParam.h263;
605 /* common parameters but id is depends on codec */
606 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP;
607 ext_ctrl[k++].value = pCommonParam->FrameQp;
608 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP;
609 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
610 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP;
611 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
612 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP;
613 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
614 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
615 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
617 /* H263 specific parameters */
618 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE
619 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE;
620 ext_ctrl[k++].value = pH263Param->FrameRate;
622 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
623 ext_ctrl[k++].value = 0;
624 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
625 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
626 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
627 ext_ctrl[k++].value = 1;
629 /* Initial parameters : Frame Skip */
630 switch (pInitParam->FrameSkip) {
631 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
632 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
633 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
635 case VIDEO_FRAME_SKIP_MODE_BUF_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_BUF_LIMIT;
640 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
641 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
642 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
645 ext_ctrls.count = H263_CTRL_NUM;
650 ALOGE("[%s] Undefined codec type",__func__);
651 ret = VIDEO_ERROR_BADPARAM;
655 ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
656 ext_ctrls.controls = ext_ctrl;
658 if (exynos_v4l2_s_ext_ctrl(pCtx->hEnc, &ext_ctrls) != 0) {
659 ALOGE("%s: Failed to s_ext_ctrl", __func__);
660 ret = VIDEO_ERROR_APIFAIL;
669 * [Encoder OPS] Set Frame Tag
671 static ExynosVideoErrorType MFC_Encoder_Set_FrameTag(
675 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
676 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
679 ALOGE("%s: Video context info must be supplied", __func__);
680 ret = VIDEO_ERROR_BADPARAM;
683 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
684 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) {
685 ALOGE("%s: Failed to s_ctrl", __func__);
686 ret = VIDEO_ERROR_APIFAIL;
695 * [Encoder OPS] Get Frame Tag
697 static int MFC_Encoder_Get_FrameTag(void *pHandle)
699 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
704 ALOGE("%s: Video context info must be supplied", __func__);
707 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
708 if (exynos_v4l2_g_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag) != 0) {
709 ALOGE("%s: Failed to g_ctrl", __func__);
718 * [Encoder OPS] Set Frame Type
720 static ExynosVideoErrorType MFC_Encoder_Set_FrameType(
722 ExynosVideoFrameType frameType)
724 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
725 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
728 ALOGE("%s: Video context info must be supplied", __func__);
729 ret = VIDEO_ERROR_BADPARAM;
734 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE, frameType) != 0) {
735 ALOGE("%s: Failed to s_ctrl", __func__);
736 ret = VIDEO_ERROR_APIFAIL;
746 * [Encoder OPS] Set Frame Rate
748 static ExynosVideoErrorType MFC_Encoder_Set_FrameRate(
752 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
753 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
756 ALOGE("%s: Video context info must be supplied", __func__);
757 ret = VIDEO_ERROR_BADPARAM;
760 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH
761 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH, frameRate) != 0) {
762 ALOGE("%s: Failed to s_ctrl", __func__);
763 ret = VIDEO_ERROR_APIFAIL;
773 * [Encoder OPS] Set Bit Rate
775 static ExynosVideoErrorType MFC_Encoder_Set_BitRate(
779 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
780 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
783 ALOGE("%s: Video context info must be supplied", __func__);
784 ret = VIDEO_ERROR_BADPARAM;
787 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH
788 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH, bitRate) != 0) {
789 ALOGE("%s: Failed to s_ctrl", __func__);
790 ret = VIDEO_ERROR_APIFAIL;
799 * [Encoder OPS] Set Frame Skip
801 static ExynosVideoErrorType MFC_Encoder_Set_FrameSkip(
805 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
806 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
809 ALOGE("%s: Video context info must be supplied", __func__);
810 ret = VIDEO_ERROR_BADPARAM;
814 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE, frameSkip) != 0) {
815 ALOGE("%s: Failed to s_ctrl", __func__);
816 ret = VIDEO_ERROR_APIFAIL;
825 * [Encoder OPS] Set IDR Period
827 static ExynosVideoErrorType MFC_Encoder_Set_IDRPeriod(
831 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
832 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
835 ALOGE("%s: Video context info must be supplied", __func__);
836 ret = VIDEO_ERROR_BADPARAM;
840 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, IDRPeriod) != 0) {
841 ALOGE("%s: Failed to s_ctrl", __func__);
842 ret = VIDEO_ERROR_APIFAIL;
851 * [Encoder OPS] Enable Prepend SPS and PPS to every IDR Frames
853 static ExynosVideoErrorType MFC_Encoder_Enable_PrependSpsPpsToIdr(void *pHandle)
855 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
856 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
859 ALOGE("%s: Video context info must be supplied", __func__);
860 ret = VIDEO_ERROR_BADPARAM;
863 #ifdef V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR
864 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR, 1) != 0) {
865 ALOGE("%s: Failed to s_ctrl", __func__);
866 ret = VIDEO_ERROR_APIFAIL;
875 * [Encoder Buffer OPS] Enable Cacheable (Input)
877 static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Inbuf(void *pHandle)
879 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
880 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
883 ALOGE("%s: Video context info must be supplied", __func__);
884 ret = VIDEO_ERROR_BADPARAM;
887 #ifdef V4L2_CID_CACHEABLE
888 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 2) != 0) {
889 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__);
890 ret = VIDEO_ERROR_APIFAIL;
899 * [Encoder Buffer OPS] Enable Cacheable (Output)
901 static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Outbuf(void *pHandle)
903 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
904 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
907 ALOGE("%s: Video context info must be supplied", __func__);
908 ret = VIDEO_ERROR_BADPARAM;
911 #ifdef V4L2_CID_CACHEABLE
912 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 1) != 0) {
913 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__);
914 ret = VIDEO_ERROR_APIFAIL;
923 * [Encoder Buffer OPS] Set Shareable Buffer (Input)
925 static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Inbuf(void *pHandle)
927 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
928 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
931 ALOGE("%s: Video context info must be supplied", __func__);
932 ret = VIDEO_ERROR_BADPARAM;
936 pCtx->bShareInbuf = VIDEO_TRUE;
943 * [Encoder Buffer OPS] Set Shareable Buffer (Output)
945 static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Outbuf(void *pHandle)
947 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
948 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
951 ALOGE("%s: Video context info must be supplied", __func__);
952 ret = VIDEO_ERROR_BADPARAM;
956 pCtx->bShareOutbuf = VIDEO_TRUE;
963 * [Encoder Buffer OPS] Get Buffer (Input)
965 static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Inbuf(
968 ExynosVideoBuffer **pBuffer)
970 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
971 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
974 ALOGE("%s: Video context info must be supplied", __func__);
976 ret = VIDEO_ERROR_NOBUFFERS;
980 if (pCtx->nInbufs <= nIndex) {
982 ret = VIDEO_ERROR_BADPARAM;
986 *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex];
993 * [Encoder Buffer OPS] Get Buffer (Output)
995 static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Outbuf(
998 ExynosVideoBuffer **pBuffer)
1000 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1001 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1004 ALOGE("%s: Video context info must be supplied", __func__);
1006 ret = VIDEO_ERROR_NOBUFFERS;
1010 if (pCtx->nOutbufs <= nIndex) {
1012 ret = VIDEO_ERROR_BADPARAM;
1016 *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex];
1023 * [Encoder Buffer OPS] Set Geometry (Src)
1025 static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Inbuf(
1027 ExynosVideoGeometry *bufferConf)
1029 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1030 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1032 struct v4l2_format fmt;
1035 ALOGE("%s: Video context info must be supplied", __func__);
1036 ret = VIDEO_ERROR_BADPARAM;
1040 if (bufferConf == NULL) {
1041 ALOGE("%s: Buffer geometry must be supplied", __func__);
1042 ret = VIDEO_ERROR_BADPARAM;
1046 memset(&fmt, 0, sizeof(fmt));
1048 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1049 fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat);
1050 fmt.fmt.pix_mp.width = bufferConf->nFrameWidth;
1051 fmt.fmt.pix_mp.height = bufferConf->nFrameHeight;
1052 fmt.fmt.pix_mp.num_planes = VIDEO_ENCODER_INBUF_PLANES;
1055 if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) {
1056 ALOGE("%s: Failed to s_fmt", __func__);
1057 ret = VIDEO_ERROR_APIFAIL;
1061 memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry));
1068 * [Encoder Buffer OPS] Get Geometry (Src)
1070 static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Inbuf(
1072 ExynosVideoGeometry *bufferConf)
1074 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1075 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1077 struct v4l2_format fmt;
1080 ALOGE("%s: Video context info must be supplied", __func__);
1081 ret = VIDEO_ERROR_BADPARAM;
1085 if (bufferConf == NULL) {
1086 ALOGE("%s: Buffer geometry must be supplied", __func__);
1087 ret = VIDEO_ERROR_BADPARAM;
1091 memset(&fmt, 0, sizeof(fmt));
1093 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1094 if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) {
1095 ALOGE("%s: Failed to g_fmt", __func__);
1096 ret = VIDEO_ERROR_APIFAIL;
1100 bufferConf->nFrameHeight = fmt.fmt.pix_mp.width;
1101 bufferConf->nFrameHeight = fmt.fmt.pix_mp.height;
1102 bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1109 * [Encoder Buffer OPS] Set Geometry (Dst)
1111 static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Outbuf(
1113 ExynosVideoGeometry *bufferConf)
1115 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1116 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1118 struct v4l2_format fmt;
1121 ALOGE("%s: Video context info must be supplied", __func__);
1122 ret = VIDEO_ERROR_BADPARAM;
1126 if (bufferConf == NULL) {
1127 ALOGE("%s: Buffer geometry must be supplied", __func__);
1128 ret = VIDEO_ERROR_BADPARAM;
1132 memset(&fmt, 0, sizeof(fmt));
1134 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1135 fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat);
1136 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage;
1138 if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) {
1139 ALOGE("%s: Failed to s_fmt", __func__);
1140 ret = VIDEO_ERROR_APIFAIL;
1144 memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry));
1151 * [Encoder Buffer OPS] Get Geometry (Dst)
1153 static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Outbuf(
1155 ExynosVideoGeometry *bufferConf)
1157 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1158 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1160 struct v4l2_format fmt;
1163 ALOGE("%s: Video context info must be supplied", __func__);
1164 ret = VIDEO_ERROR_BADPARAM;
1168 if (bufferConf == NULL) {
1169 ALOGE("%s: Buffer geometry must be supplied", __func__);
1170 ret = VIDEO_ERROR_BADPARAM;
1174 memset(&fmt, 0, sizeof(fmt));
1176 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1177 if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) {
1178 ALOGE("%s: Failed to g_fmt", __func__);
1179 ret = VIDEO_ERROR_APIFAIL;
1184 bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1191 * [Encoder Buffer OPS] Setup (Src)
1193 static ExynosVideoErrorType MFC_Encoder_Setup_Inbuf(
1195 unsigned int nBufferCount)
1197 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1198 ExynosVideoPlane *pVideoPlane = NULL;
1199 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1201 struct v4l2_requestbuffers req;
1202 struct v4l2_buffer buf;
1203 struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES];
1207 ALOGE("%s: Video context info must be supplied", __func__);
1208 ret = VIDEO_ERROR_BADPARAM;
1212 if (nBufferCount == 0) {
1213 ALOGE("%s: Buffer count must be greater than 0", __func__);
1214 ret = VIDEO_ERROR_BADPARAM;
1218 memset(&req, 0, sizeof(req));
1220 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1221 req.count = nBufferCount;
1223 if (pCtx->bShareInbuf == VIDEO_TRUE)
1224 req.memory = pCtx->nMemoryType;
1226 req.memory = V4L2_MEMORY_MMAP;
1228 if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) {
1229 ALOGE("Failed to require buffer");
1230 ret = VIDEO_ERROR_APIFAIL;
1234 pCtx->nInbufs = (int)req.count;
1236 pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
1237 if (pCtx->pInbuf == NULL) {
1238 ALOGE("%s: Failed to allocate input buffer context", __func__);
1239 ret = VIDEO_ERROR_NOMEM;
1242 memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
1244 memset(&buf, 0, sizeof(buf));
1246 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1247 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1248 buf.memory = V4L2_MEMORY_MMAP;
1249 buf.m.planes = planes;
1250 buf.length = VIDEO_ENCODER_INBUF_PLANES;
1252 for (i = 0; i < pCtx->nInbufs; i++) {
1254 if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) {
1255 ALOGE("%s: Failed to querybuf", __func__);
1256 ret = VIDEO_ERROR_APIFAIL;
1260 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
1261 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1262 pVideoPlane->addr = mmap(NULL,
1263 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1264 MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset);
1266 if (pVideoPlane->addr == MAP_FAILED) {
1267 ALOGE("%s: Failed to map", __func__);
1268 ret = VIDEO_ERROR_MAPFAIL;
1272 pVideoPlane->allocSize = buf.m.planes[j].length;
1273 pVideoPlane->dataSize = 0;
1276 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
1277 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1278 pCtx->pInbuf[i].bRegistered = VIDEO_TRUE;
1282 for (i = 0; i < pCtx->nInbufs; i++) {
1283 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
1284 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1285 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
1292 if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) {
1293 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1294 for (i = 0; i < pCtx->nInbufs; i++) {
1295 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
1296 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1297 if (pVideoPlane->addr == MAP_FAILED) {
1298 pVideoPlane->addr = NULL;
1302 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1314 * [Encoder Buffer OPS] Setup (Dst)
1316 static ExynosVideoErrorType MFC_Encoder_Setup_Outbuf(
1318 unsigned int nBufferCount)
1320 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1321 ExynosVideoPlane *pVideoPlane = NULL;
1322 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1324 struct v4l2_requestbuffers req;
1325 struct v4l2_buffer buf;
1326 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
1330 ALOGE("%s: Video context info must be supplied", __func__);
1331 ret = VIDEO_ERROR_BADPARAM;
1335 if (nBufferCount == 0) {
1336 ALOGE("%s: Buffer count must be greater than 0", __func__);
1337 ret = VIDEO_ERROR_BADPARAM;
1341 memset(&req, 0, sizeof(req));
1343 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1344 req.count = nBufferCount;
1346 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1347 req.memory = pCtx->nMemoryType;
1349 req.memory = V4L2_MEMORY_MMAP;
1351 if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) {
1352 ALOGE("%s: Failed to reqbuf", __func__);
1353 ret = VIDEO_ERROR_APIFAIL;
1357 pCtx->nOutbufs = req.count;
1359 pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1360 if (pCtx->pOutbuf == NULL) {
1361 ALOGE("%s: Failed to allocate output buffer context", __func__);
1362 ret = VIDEO_ERROR_NOMEM;
1365 memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1367 memset(&buf, 0, sizeof(buf));
1369 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1370 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1371 buf.memory = V4L2_MEMORY_MMAP;
1372 buf.m.planes = planes;
1373 buf.length = VIDEO_ENCODER_OUTBUF_PLANES;
1375 for (i = 0; i < pCtx->nOutbufs; i++) {
1377 if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) {
1378 ALOGE("%s: Failed to querybuf", __func__);
1379 ret = VIDEO_ERROR_APIFAIL;
1383 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
1384 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1385 pVideoPlane->addr = mmap(NULL,
1386 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1387 MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset);
1389 if (pVideoPlane->addr == MAP_FAILED) {
1390 ALOGE("%s: Failed to map", __func__);
1391 ret = VIDEO_ERROR_MAPFAIL;
1395 pVideoPlane->allocSize = buf.m.planes[j].length;
1396 pVideoPlane->dataSize = 0;
1399 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1400 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1401 pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE;
1404 for (i = 0; i < pCtx->nOutbufs; i++ ) {
1405 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1406 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1407 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
1414 if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) {
1415 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1416 for (i = 0; i < pCtx->nOutbufs; i++) {
1417 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
1418 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1419 if (pVideoPlane->addr == MAP_FAILED) {
1420 pVideoPlane->addr = NULL;
1424 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1429 free(pCtx->pOutbuf);
1436 * [Encoder Buffer OPS] Run (src)
1438 static ExynosVideoErrorType MFC_Encoder_Run_Inbuf(void *pHandle)
1440 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1441 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1444 ALOGE("%s: Video context info must be supplied", __func__);
1445 ret = VIDEO_ERROR_BADPARAM;
1449 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1450 if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1451 ALOGE("%s: Failed to streamon for input buffer", __func__);
1452 ret = VIDEO_ERROR_APIFAIL;
1455 pCtx->bStreamonInbuf = VIDEO_TRUE;
1463 * [Encoder Buffer OPS] Run (Dst)
1465 static ExynosVideoErrorType MFC_Encoder_Run_Outbuf(void *pHandle)
1467 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1468 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1471 ALOGE("%s: Video context info must be supplied", __func__);
1472 ret = VIDEO_ERROR_BADPARAM;
1476 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1477 if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1478 ALOGE("%s: Failed to streamon for output buffer", __func__);
1479 ret = VIDEO_ERROR_APIFAIL;
1482 pCtx->bStreamonOutbuf = VIDEO_TRUE;
1490 * [Encoder Buffer OPS] Stop (Src)
1492 static ExynosVideoErrorType MFC_Encoder_Stop_Inbuf(void *pHandle)
1494 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1495 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1499 ALOGE("%s: Video context info must be supplied", __func__);
1500 ret = VIDEO_ERROR_BADPARAM;
1504 if (pCtx->bStreamonInbuf == VIDEO_TRUE) {
1505 if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1506 ALOGE("%s: Failed to streamoff for input buffer", __func__);
1507 ret = VIDEO_ERROR_APIFAIL;
1510 pCtx->bStreamonInbuf = VIDEO_FALSE;
1513 for (i = 0; i < pCtx->nInbufs; i++) {
1514 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1522 * [Encoder Buffer OPS] Stop (Dst)
1524 static ExynosVideoErrorType MFC_Encoder_Stop_Outbuf(void *pHandle)
1526 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1527 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1531 ALOGE("%s: Video context info must be supplied", __func__);
1532 ret = VIDEO_ERROR_BADPARAM;
1536 if (pCtx->bStreamonOutbuf == VIDEO_TRUE) {
1537 if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1538 ALOGE("%s: Failed to streamoff for output buffer", __func__);
1539 ret = VIDEO_ERROR_APIFAIL;
1542 pCtx->bStreamonOutbuf = VIDEO_FALSE;
1545 for (i = 0; i < pCtx->nOutbufs; i++) {
1546 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1555 * [Encoder Buffer OPS] Wait (Src)
1557 static ExynosVideoErrorType MFC_Encoder_Wait_Inbuf(void *pHandle)
1559 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1560 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1562 struct pollfd poll_events;
1566 ALOGE("%s: Video context info must be supplied", __func__);
1567 ret = VIDEO_ERROR_BADPARAM;
1571 poll_events.fd = pCtx->hEnc;
1572 poll_events.events = POLLOUT | POLLERR;
1573 poll_events.revents = 0;
1576 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
1577 if (poll_state > 0) {
1578 if (poll_events.revents & POLLOUT) {
1581 ALOGE("%s: Poll return error", __func__);
1582 ret = VIDEO_ERROR_POLL;
1585 } else if (poll_state < 0) {
1586 ALOGE("%s: Poll state error", __func__);
1587 ret = VIDEO_ERROR_POLL;
1590 } while (poll_state == 0);
1597 * [Encoder Buffer OPS] Wait (Dst)
1599 static ExynosVideoErrorType MFC_Encoder_Wait_Outbuf(void *pHandle)
1601 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1602 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1604 struct pollfd poll_events;
1606 int bframe_count = 0; // FIXME
1609 ALOGE("%s: Video context info must be supplied", __func__);
1610 ret = VIDEO_ERROR_BADPARAM;
1614 poll_events.fd = pCtx->hEnc;
1615 poll_events.events = POLLIN | POLLERR;
1616 poll_events.revents = 0;
1619 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
1620 if (poll_state > 0) {
1621 if (poll_events.revents & POLLIN) {
1624 ALOGE("%s: Poll return error", __func__);
1625 ret = VIDEO_ERROR_POLL;
1628 } else if (poll_state < 0) {
1629 ALOGE("%s: Poll state error", __func__);
1630 ret = VIDEO_ERROR_POLL;
1633 bframe_count++; // FIXME
1635 } while (poll_state == 0 && bframe_count < 5); // FIXME
1642 static ExynosVideoErrorType MFC_Encoder_Register_Inbuf(
1644 ExynosVideoPlane *planes,
1647 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1648 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1651 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_INBUF_PLANES)) {
1652 ALOGE("%s: input params must be supplied", __func__);
1653 ret = VIDEO_ERROR_BADPARAM;
1657 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1658 if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) {
1660 for (plane = 0; plane < nPlanes; plane++) {
1661 pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr;
1662 pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1663 pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd;
1664 ALOGV("%s: addr = 0x%x", __func__, pCtx->pInbuf[nIndex].planes[plane].addr);
1666 pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE;
1671 if (nIndex == pCtx->nInbufs) {
1672 ALOGE("%s: can not find non-registered input buffer", __func__);
1673 ret = VIDEO_ERROR_NOBUFFERS;
1680 static ExynosVideoErrorType MFC_Encoder_Register_Outbuf(
1682 ExynosVideoPlane *planes,
1685 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1686 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1689 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_OUTBUF_PLANES)) {
1690 ALOGE("%s: params must be supplied", __func__);
1691 ret = VIDEO_ERROR_BADPARAM;
1695 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1696 if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) {
1698 for (plane = 0; plane < nPlanes; plane++) {
1699 pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr;
1700 pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1701 pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd;
1703 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE;
1708 if (nIndex == pCtx->nOutbufs) {
1709 ALOGE("%s: can not find non-registered output buffer", __func__);
1710 ret = VIDEO_ERROR_NOBUFFERS;
1717 static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
1719 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1720 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1724 ALOGE("%s: Video context info must be supplied", __func__);
1725 ret = VIDEO_ERROR_BADPARAM;
1729 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1730 pCtx->pInbuf[nIndex].planes[0].addr = NULL;
1731 pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE;
1738 static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
1740 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1741 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1745 ALOGE("%s: Video context info must be supplied", __func__);
1746 ret = VIDEO_ERROR_BADPARAM;
1750 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1751 pCtx->pOutbuf[nIndex].planes[0].addr = NULL;
1752 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE;
1760 * [Encoder Buffer OPS] Find (Input)
1762 static int MFC_Encoder_Find_Inbuf(
1764 unsigned char *pBuffer)
1766 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1770 ALOGE("%s: Video context info must be supplied", __func__);
1774 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1775 if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) {
1776 if ((pBuffer == NULL) ||
1777 (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer))
1782 if (nIndex == pCtx->nInbufs)
1790 * [Encoder Buffer OPS] Find (Output)
1792 static int MFC_Encoder_Find_Outbuf(
1794 unsigned char *pBuffer)
1796 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1800 ALOGE("%s: Video context info must be supplied", __func__);
1804 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1805 if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) {
1806 if ((pBuffer == NULL) ||
1807 (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer))
1812 if (nIndex == pCtx->nOutbufs)
1820 * [Encoder Buffer OPS] Enqueue (Input)
1822 static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf(
1824 unsigned char *pBuffer[],
1825 unsigned int dataSize[],
1829 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1830 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1831 pthread_mutex_t *pMutex = NULL;
1833 struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES];
1834 struct v4l2_buffer buf;
1838 ALOGE("%s: Video context info must be supplied", __func__);
1839 ret = VIDEO_ERROR_BADPARAM;
1843 if (VIDEO_ENCODER_INBUF_PLANES < nPlanes) {
1844 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1845 VIDEO_ENCODER_INBUF_PLANES, nPlanes);
1846 ret = VIDEO_ERROR_BADPARAM;
1850 memset(&planes,0,sizeof(planes));
1851 memset(&buf, 0, sizeof(buf));
1853 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1854 buf.m.planes = planes;
1855 buf.length = VIDEO_ENCODER_INBUF_PLANES;
1857 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
1858 pthread_mutex_lock(pMutex);
1859 index = MFC_Encoder_Find_Inbuf(pCtx, pBuffer[0]);
1861 pthread_mutex_unlock(pMutex);
1862 ALOGE("%s: Failed to get index", __func__);
1863 ret = VIDEO_ERROR_NOBUFFERS;
1868 pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE;
1869 pthread_mutex_unlock(pMutex);
1871 if (pCtx->bShareInbuf == VIDEO_TRUE) {
1872 buf.memory = pCtx->nMemoryType;
1874 for (i = 0; i < nPlanes; i++) {
1875 /* V4L2_MEMORY_USERPTR */
1876 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1877 buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize;
1878 /* V4L2_MEMORY_DMABUF */
1879 #ifdef TIZEN_FEATURE_E3250 /* #ifdef USE_DMA_BUF */
1880 buf.m.planes[i].m.fd = pCtx->pInbuf[buf.index].planes[i].fd;
1881 buf.m.planes[i].length = 0; /* kernel give the length */
1883 buf.m.planes[i].bytesused = dataSize[i];
1886 buf.memory = V4L2_MEMORY_MMAP;
1887 for (i = 0; i < nPlanes; i++)
1888 buf.m.planes[i].bytesused = dataSize[i];
1891 ALOGE("call exynos_v4l2_qbuf(): %d", buf.m.planes[0].m.fd);
1892 if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) {
1893 ALOGE("%s: Failed to enqueue input buffer", __func__);
1894 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1895 ret = VIDEO_ERROR_APIFAIL;
1899 pCtx->pInbuf[buf.index].pPrivate = pPrivate;
1906 * [Encoder Buffer OPS] Enqueue (Output)
1908 static ExynosVideoErrorType MFC_Encoder_Enqueue_Outbuf(
1910 unsigned char *pBuffer[],
1911 unsigned int dataSize[],
1915 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1916 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1917 pthread_mutex_t *pMutex = NULL;
1919 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
1920 struct v4l2_buffer buf;
1924 ALOGE("%s: Video context info must be supplied", __func__);
1925 ret = VIDEO_ERROR_BADPARAM;
1929 if (VIDEO_ENCODER_OUTBUF_PLANES < nPlanes) {
1930 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1931 VIDEO_ENCODER_OUTBUF_PLANES, nPlanes);
1932 ret = VIDEO_ERROR_BADPARAM;
1936 memset(&buf, 0, sizeof(buf));
1938 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1939 buf.m.planes = planes;
1940 buf.length = VIDEO_ENCODER_OUTBUF_PLANES;
1942 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
1943 pthread_mutex_lock(pMutex);
1944 index = MFC_Encoder_Find_Outbuf(pCtx, pBuffer[0]);
1946 pthread_mutex_unlock(pMutex);
1947 ALOGE("%s: Failed to get index", __func__);
1948 ret = VIDEO_ERROR_NOBUFFERS;
1952 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE;
1953 pthread_mutex_unlock(pMutex);
1955 if (pCtx->bShareOutbuf == VIDEO_TRUE) {
1956 buf.memory = pCtx->nMemoryType;
1957 for (i = 0; i < nPlanes; i++) {
1958 /* V4L2_MEMORY_USERPTR */
1959 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1960 buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize;
1961 /* V4L2_MEMORY_DMABUF */
1963 buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd;
1964 buf.m.planes[i].length = 0; /* kernel give the length */
1966 buf.m.planes[i].bytesused = dataSize[i];
1969 buf.memory = V4L2_MEMORY_MMAP;
1972 if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) {
1973 ALOGE("%s: Failed to enqueue output buffer", __func__);
1974 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE;
1975 ret = VIDEO_ERROR_APIFAIL;
1979 pCtx->pOutbuf[buf.index].pPrivate = pPrivate;
1987 * [Encoder Buffer OPS] Enqueue All (Output)
1989 static ExynosVideoErrorType MFC_Encoder_Enqueue_All_Outbuf(void *pHandle)
1991 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1992 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1994 unsigned char *pBuffer[VIDEO_BUFFER_MAX_PLANES] = {NULL, };
1995 unsigned int dataSize[VIDEO_BUFFER_MAX_PLANES] = {0, };
2000 ALOGE("%s: Video context info must be supplied", __func__);
2001 ret = VIDEO_ERROR_BADPARAM;
2005 for (i = 0; i < pCtx->nOutbufs; i++) {
2006 ret = MFC_Encoder_Enqueue_Outbuf(pCtx, pBuffer, dataSize, 1, NULL);
2007 if (ret != VIDEO_ERROR_NONE)
2017 * [Encoder Buffer OPS] Dequeue (Input)
2019 static ExynosVideoBuffer *MFC_Encoder_Dequeue_Inbuf(void *pHandle)
2021 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2022 ExynosVideoBuffer *pInbuf = NULL;
2024 struct v4l2_buffer buf;
2027 ALOGE("%s: Video context info must be supplied", __func__);
2031 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
2036 memset(&buf, 0, sizeof(buf));
2038 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2040 if (pCtx->bShareInbuf == VIDEO_TRUE)
2041 buf.memory = pCtx->nMemoryType;
2043 buf.memory = V4L2_MEMORY_MMAP;
2045 if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) {
2050 pInbuf = &pCtx->pInbuf[buf.index];
2051 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
2058 * [Encoder Buffer OPS] Dequeue (Output)
2060 static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle)
2062 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2063 ExynosVideoBuffer *pOutbuf = NULL;
2065 struct v4l2_buffer buf;
2066 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
2069 ALOGE("%s: Video context info must be supplied", __func__);
2073 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
2078 memset(&buf, 0, sizeof(buf));
2080 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2081 buf.m.planes = planes;
2084 if (pCtx->bShareOutbuf == VIDEO_TRUE)
2085 buf.memory = pCtx->nMemoryType;
2087 buf.memory = V4L2_MEMORY_MMAP;
2089 /* no error case for output buffer dequeue in encoder */
2090 if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) {
2094 pOutbuf = &pCtx->pOutbuf[buf.index];
2095 pOutbuf->planes[0].dataSize = buf.m.planes[0].bytesused;
2097 switch (buf.flags & (0x7 << 3)) {
2098 case V4L2_BUF_FLAG_KEYFRAME:
2099 pOutbuf->frameType = VIDEO_FRAME_I;
2101 case V4L2_BUF_FLAG_PFRAME:
2102 pOutbuf->frameType = VIDEO_FRAME_P;
2104 case V4L2_BUF_FLAG_BFRAME:
2105 pOutbuf->frameType = VIDEO_FRAME_B;
2108 ALOGI("%s: encoded frame type is = %d",__func__, (buf.flags & (0x7 << 3)));
2109 pOutbuf->frameType = VIDEO_FRAME_OTHERS;
2113 pOutbuf->bQueued = VIDEO_FALSE;
2119 static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Inbuf(void *pHandle)
2121 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2122 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2126 ALOGE("%s: Video context info must be supplied", __func__);
2127 ret = VIDEO_ERROR_BADPARAM;
2131 for (i = 0; i < pCtx->nInbufs; i++) {
2132 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
2139 static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Outbuf(void *pHandle)
2141 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2142 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2146 ALOGE("%s: Video context info must be supplied", __func__);
2147 ret = VIDEO_ERROR_BADPARAM;
2151 for (i = 0; i < pCtx->nOutbufs; i++) {
2152 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
2160 * [Encoder OPS] Common
2162 static ExynosVideoEncOps defEncOps = {
2164 .Init = MFC_Encoder_Init,
2165 .Finalize = MFC_Encoder_Finalize,
2166 .Set_EncParam = MFC_Encoder_Set_EncParam,
2167 .Set_FrameType = MFC_Encoder_Set_FrameType,
2168 .Set_FrameRate = MFC_Encoder_Set_FrameRate,
2169 .Set_BitRate = MFC_Encoder_Set_BitRate,
2170 .Set_FrameSkip = MFC_Encoder_Set_FrameSkip,
2171 .Set_IDRPeriod = MFC_Encoder_Set_IDRPeriod,
2172 .Set_FrameTag = MFC_Encoder_Set_FrameTag,
2173 .Get_FrameTag = MFC_Encoder_Get_FrameTag,
2174 .Enable_PrependSpsPpsToIdr = MFC_Encoder_Enable_PrependSpsPpsToIdr,
2178 * [Encoder Buffer OPS] Input
2180 static ExynosVideoEncBufferOps defInbufOps = {
2182 .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Inbuf,
2183 .Set_Shareable = MFC_Encoder_Set_Shareable_Inbuf,
2184 .Get_Buffer = MFC_Encoder_Get_Buffer_Inbuf,
2185 .Set_Geometry = MFC_Encoder_Set_Geometry_Inbuf,
2186 .Get_Geometry = MFC_Encoder_Get_Geometry_Inbuf,
2187 .Setup = MFC_Encoder_Setup_Inbuf,
2188 .Run = MFC_Encoder_Run_Inbuf,
2189 .Stop = MFC_Encoder_Stop_Inbuf,
2190 .Enqueue = MFC_Encoder_Enqueue_Inbuf,
2191 .Enqueue_All = NULL,
2192 .Dequeue = MFC_Encoder_Dequeue_Inbuf,
2193 .Register = MFC_Encoder_Register_Inbuf,
2194 .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Inbuf,
2195 .Clear_Queue = MFC_Encoder_Clear_Queued_Inbuf,
2199 * [Encoder Buffer OPS] Output
2201 static ExynosVideoEncBufferOps defOutbufOps = {
2203 .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Outbuf,
2204 .Set_Shareable = MFC_Encoder_Set_Shareable_Outbuf,
2205 .Get_Buffer = MFC_Encoder_Get_Buffer_Outbuf,
2206 .Set_Geometry = MFC_Encoder_Set_Geometry_Outbuf,
2207 .Get_Geometry = MFC_Encoder_Get_Geometry_Outbuf,
2208 .Setup = MFC_Encoder_Setup_Outbuf,
2209 .Run = MFC_Encoder_Run_Outbuf,
2210 .Stop = MFC_Encoder_Stop_Outbuf,
2211 .Enqueue = MFC_Encoder_Enqueue_Outbuf,
2212 .Enqueue_All = NULL,
2213 .Dequeue = MFC_Encoder_Dequeue_Outbuf,
2214 .Register = MFC_Encoder_Register_Outbuf,
2215 .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Outbuf,
2216 .Clear_Queue = MFC_Encoder_Clear_Queued_Outbuf,
2219 int Exynos_Video_Register_Encoder(
2220 ExynosVideoEncOps *pEncOps,
2221 ExynosVideoEncBufferOps *pInbufOps,
2222 ExynosVideoEncBufferOps *pOutbufOps)
2224 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2226 if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
2227 ret = VIDEO_ERROR_BADPARAM;
2231 defEncOps.nSize = sizeof(defEncOps);
2232 defInbufOps.nSize = sizeof(defInbufOps);
2233 defOutbufOps.nSize = sizeof(defOutbufOps);
2235 memcpy((char *)pEncOps + sizeof(pEncOps->nSize), (char *)&defEncOps + sizeof(defEncOps.nSize),
2236 pEncOps->nSize - sizeof(pEncOps->nSize));
2238 memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
2239 pInbufOps->nSize - sizeof(pInbufOps->nSize));
2241 memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
2242 pOutbufOps->nSize - sizeof(pOutbufOps->nSize));