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 //#include <mm_ta/mm_ta.h>
48 /* #define LOG_NDEBUG 0 */
49 #define LOG_TAG "ExynosVideoEncoder"
50 #ifndef SLP_PLATFORM /* build env */
51 #include <utils/Log.h>
53 #include "Exynos_OSAL_Log.h"
56 #define MAX_CTRL_NUM 91
57 #define H264_CTRL_NUM 91
58 #define MPEG4_CTRL_NUM 26
59 #define H263_CTRL_NUM 18
61 /* FIXME: build error related with kernel-header pkg */
63 #ifndef V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR
64 #define V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_MFC_BASE + 46)
68 * [Common] __CodingType_To_V4L2PixelFormat
70 static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType)
72 unsigned int pixelformat = V4L2_PIX_FMT_H264;
75 case VIDEO_CODING_AVC:
76 pixelformat = V4L2_PIX_FMT_H264;
78 case VIDEO_CODING_MPEG4:
79 pixelformat = V4L2_PIX_FMT_MPEG4;
81 case VIDEO_CODING_VP8:
82 pixelformat = V4L2_PIX_FMT_VP8;
84 case VIDEO_CODING_H263:
85 pixelformat = V4L2_PIX_FMT_H263;
87 case VIDEO_CODING_VC1:
88 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G;
90 case VIDEO_CODING_VC1_RCV:
91 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L;
93 case VIDEO_CODING_MPEG2:
94 pixelformat = V4L2_PIX_FMT_MPEG2;
97 pixelformat = V4L2_PIX_FMT_H264;
105 * [Common] __ColorFormatType_To_V4L2PixelFormat
107 static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType)
109 unsigned int pixelformat = V4L2_PIX_FMT_NV12M;
111 switch (colorFormatType) {
112 case VIDEO_COLORFORMAT_NV12_TILED:
114 pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
116 pixelformat = V4L2_PIX_FMT_NV12MT;
120 case VIDEO_COLORFORMAT_NV21:
121 pixelformat = V4L2_PIX_FMT_NV21M;
124 case VIDEO_COLORFORMAT_NV12:
126 pixelformat = V4L2_PIX_FMT_NV12M;
136 static void *MFC_Encoder_Init(int nMemoryType)
138 ExynosVideoEncContext *pCtx = NULL;
139 pthread_mutex_t *pMutex = NULL;
140 int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING);
142 pCtx = (ExynosVideoEncContext *)malloc(sizeof(*pCtx));
144 ALOGE("%s: Failed to allocate encoder context buffer", __func__);
145 goto EXIT_ALLOC_FAIL;
148 memset(pCtx, 0, sizeof(*pCtx));
150 pCtx->hEnc = exynos_v4l2_open_devname(VIDEO_ENCODER_NAME, O_RDWR, 0);
151 if (pCtx->hEnc < 0) {
152 ALOGE("%s: Failed to open encoder device", __func__);
156 if (!exynos_v4l2_querycap(pCtx->hEnc, needCaps)) {
157 ALOGE("%s: Failed to querycap", __func__);
158 goto EXIT_QUERYCAP_FAIL;
161 pCtx->bStreamonInbuf = VIDEO_FALSE;
162 pCtx->bStreamonOutbuf = VIDEO_FALSE;
164 pCtx->nMemoryType = nMemoryType;
166 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
167 if (pMutex == NULL) {
168 ALOGE("%s: Failed to allocate mutex about input buffer", __func__);
169 goto EXIT_QUERYCAP_FAIL;
171 if (pthread_mutex_init(pMutex, NULL) != 0) {
173 goto EXIT_QUERYCAP_FAIL;
175 pCtx->pInMutex = (void*)pMutex;
177 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
178 if (pMutex == NULL) {
179 ALOGE("%s: Failed to allocate mutex about output buffer", __func__);
180 goto EXIT_QUERYCAP_FAIL;
182 if (pthread_mutex_init(pMutex, NULL) != 0) {
184 goto EXIT_QUERYCAP_FAIL;
186 pCtx->pOutMutex = (void*)pMutex;
191 if (pCtx->pInMutex != NULL) {
192 pthread_mutex_destroy(pCtx->pInMutex);
193 free(pCtx->pInMutex);
196 if (pCtx->pOutMutex != NULL) {
197 pthread_mutex_destroy(pCtx->pOutMutex);
198 free(pCtx->pOutMutex);
211 * [Encoder OPS] Finalize
213 static ExynosVideoErrorType MFC_Encoder_Finalize(void *pHandle)
215 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
216 ExynosVideoPlane *pVideoPlane = NULL;
217 pthread_mutex_t *pMutex = NULL;
218 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
222 ALOGE("%s: Video context info must be supplied", __func__);
223 ret = VIDEO_ERROR_BADPARAM;
227 if (pCtx->pOutMutex != NULL) {
228 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
229 pthread_mutex_destroy(pMutex);
231 pCtx->pOutMutex = NULL;
234 if (pCtx->pInMutex != NULL) {
235 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
236 pthread_mutex_destroy(pMutex);
238 pCtx->pInMutex = NULL;
241 if (pCtx->bShareInbuf == VIDEO_FALSE) {
242 for (i = 0; i < pCtx->nInbufs; i++) {
243 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
244 pVideoPlane = &pCtx->pInbuf[i].planes[j];
245 if (pVideoPlane->addr != NULL) {
246 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
247 pVideoPlane->addr = NULL;
248 pVideoPlane->allocSize = 0;
249 pVideoPlane->dataSize = 0;
252 pCtx->pInbuf[i].pGeometry = NULL;
253 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
254 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
259 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
260 for (i = 0; i < pCtx->nOutbufs; i++) {
261 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
262 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
263 if (pVideoPlane->addr != NULL) {
264 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
265 pVideoPlane->addr = NULL;
266 pVideoPlane->allocSize = 0;
267 pVideoPlane->dataSize = 0;
270 pCtx->pOutbuf[i].pGeometry = NULL;
271 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
272 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
277 if (pCtx->pInbuf != NULL)
280 if (pCtx->pOutbuf != NULL)
293 * [Encoder OPS] Set Extended Control
295 static ExynosVideoErrorType MFC_Encoder_Set_EncParam (
297 ExynosVideoEncParam *pEncParam)
299 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
300 ExynosVideoEncInitParam *pInitParam = NULL;
301 ExynosVideoEncCommonParam *pCommonParam = NULL;
303 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
306 struct v4l2_ext_control ext_ctrl[MAX_CTRL_NUM];
307 struct v4l2_ext_controls ext_ctrls;
310 if ((pCtx == NULL) || (pEncParam == NULL)) {
311 ALOGE("%s: Video context info must be supplied", __func__);
312 ret = VIDEO_ERROR_BADPARAM;
316 pInitParam = &pEncParam->initParam;
317 pCommonParam = &pEncParam->commonParam;
319 /* common parameters */
320 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
321 ext_ctrl[k++].value = pCommonParam->IDRPeriod;
322 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
323 ext_ctrl[k++].value = pCommonParam->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */
324 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB;
325 ext_ctrl[k++].value = pCommonParam->RandomIntraMBRefresh;
326 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING;
327 ext_ctrl[k++].value = pCommonParam->PadControlOn;
328 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV;
329 ext_ctrl[k].value = pCommonParam->CrPadVal;
330 ext_ctrl[k].value |= (pCommonParam->CbPadVal << 8);
331 ext_ctrl[k++].value |= (pCommonParam->LumaPadVal << 16);
332 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
333 ext_ctrl[k++].value = pCommonParam->EnableFRMRateControl;
334 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
335 ext_ctrl[k++].value = pCommonParam->EnableMBRateControl;
336 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_BITRATE;
338 /* FIXME temporary fix */
339 if (pCommonParam->Bitrate)
340 ext_ctrl[k++].value = pCommonParam->Bitrate;
342 ext_ctrl[k++].value = 1; /* just for testing Movie studio */
344 /* codec specific parameters */
345 switch (pEncParam->eCompressionFormat) {
346 case VIDEO_CODING_AVC:
348 ExynosVideoEncH264Param *pH264Param = &pEncParam->codecParam.h264;
350 /* common parameters but id is depends on codec */
351 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
352 ext_ctrl[k++].value = pCommonParam->FrameQp;
353 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
354 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
355 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
356 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
357 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
358 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
359 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
360 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
362 /* H.264 specific parameters */
363 switch (pCommonParam->SliceMode) {
365 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
366 ext_ctrl[k++].value = 1; /* default */
367 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
368 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
371 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
372 ext_ctrl[k++].value = pH264Param->SliceArgument;
373 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
374 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
376 case 2: /* Fixed Byte number Slice mode */
377 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
378 ext_ctrl[k++].value = 1; /* default */
379 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
380 ext_ctrl[k++].value = pH264Param->SliceArgument;
386 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
387 ext_ctrl[k++].value = pH264Param->ProfileIDC;
388 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
389 ext_ctrl[k++].value = pH264Param->LevelIDC;
390 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P;
391 ext_ctrl[k++].value = pH264Param->NumberRefForPframes;
393 * It should be set using h264Param->NumberBFrames after being handled by appl.
395 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
396 ext_ctrl[k++].value = pH264Param->NumberBFrames;
397 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
398 ext_ctrl[k++].value = pH264Param->LoopFilterDisable;
399 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
400 ext_ctrl[k++].value = pH264Param->LoopFilterAlphaC0Offset;
401 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
402 ext_ctrl[k++].value = pH264Param->LoopFilterBetaOffset;
403 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
404 ext_ctrl[k++].value = pH264Param->SymbolMode;
405 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE
406 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE;
407 ext_ctrl[k++].value = pH264Param->PictureInterlace;
409 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM;
410 ext_ctrl[k++].value = pH264Param->Transform8x8Mode;
411 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE
412 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE;
413 ext_ctrl[k++].value = pH264Param->FrameRate;
415 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
416 ext_ctrl[k++].value = pH264Param->FrameQp_B;
418 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK;
419 ext_ctrl[k++].value = pH264Param->DarkDisable;
420 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH;
421 ext_ctrl[k++].value = pH264Param->SmoothDisable;
422 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC;
423 ext_ctrl[k++].value = pH264Param->StaticDisable;
424 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY;
425 ext_ctrl[k++].value = pH264Param->ActivityDisable;
427 /* doesn't have to be set */
428 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE;
429 ext_ctrl[k++].value = 1;
430 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD;
431 ext_ctrl[k++].value = 10;
432 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
433 ext_ctrl[k++].value = 0;
434 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
435 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; /* 0: seperated header, 1: header + first frame */
436 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE;
437 ext_ctrl[k++].value = 0;
438 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC;
439 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED;
440 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH;
441 ext_ctrl[k++].value = 0;
442 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT;
443 ext_ctrl[k++].value = 0;
445 /* Initial parameters : Frame Skip */
446 switch (pInitParam->FrameSkip) {
447 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
449 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
450 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
452 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
453 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
454 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
457 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
458 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
459 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
463 /* SVC is not supported yet */
464 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING;
465 ext_ctrl[k++].value = 0;
466 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
467 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B;
468 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
469 ext_ctrl[k++].value = 3;
470 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
471 ext_ctrl[k++].value = (0 << 16 | 0);
472 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
473 ext_ctrl[k++].value = (1 << 16 | 0);
474 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
475 ext_ctrl[k++].value = (2 << 16 | 0);
476 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING;
477 ext_ctrl[k++].value = 0;
478 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0;
479 ext_ctrl[k++].value = 0;
480 #ifdef V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE
481 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE;
482 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE;
484 /* FMO is not supported yet */
485 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO;
486 ext_ctrl[k++].value = 0;
487 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE;
488 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES;
489 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP;
490 ext_ctrl[k++].value = 4;
491 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
492 ext_ctrl[k++].value = (0 << 30 | 0);
493 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
494 ext_ctrl[k++].value = (1 << 30 | 0);
495 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
496 ext_ctrl[k++].value = (2 << 30 | 0);
497 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
498 ext_ctrl[k++].value = (3 << 30 | 0);
499 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION;
500 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT;
501 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE;
502 ext_ctrl[k++].value = 0;
504 /* ASO is not supported yet */
505 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO;
506 ext_ctrl[k++].value = 0;
508 for (i = 0; i < 32; i++) {
509 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER;
510 ext_ctrl[k++].value = (i << 16 | 0);
513 ext_ctrls.count = H264_CTRL_NUM;
517 case VIDEO_CODING_MPEG4:
519 ExynosVideoEncMpeg4Param *pMpeg4Param = &pEncParam->codecParam.mpeg4;
521 /* common parameters but id is depends on codec */
522 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP;
523 ext_ctrl[k++].value = pCommonParam->FrameQp;
524 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP;
525 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
526 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP;
527 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
528 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP;
529 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
530 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
531 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
533 /* MPEG4 specific parameters */
534 switch (pCommonParam->SliceMode) {
536 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
537 ext_ctrl[k++].value = 1; /* default */
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 = pMpeg4Param->SliceArgument;
544 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
545 ext_ctrl[k++].value = 2800; /* based on MFC6.x */
548 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
549 ext_ctrl[k++].value = 1; /* default */
550 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
551 ext_ctrl[k++].value = pMpeg4Param->SliceArgument;
557 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
558 ext_ctrl[k++].value = pMpeg4Param->ProfileIDC;
559 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
560 ext_ctrl[k++].value = pMpeg4Param->LevelIDC;
561 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL;
562 ext_ctrl[k++].value = pMpeg4Param->DisableQpelME;
565 * It should be set using mpeg4Param->NumberBFrames after being handled by appl.
567 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
568 ext_ctrl[k++].value = pMpeg4Param->NumberBFrames;
569 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES
570 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES;
571 ext_ctrl[k++].value = pMpeg4Param->TimeIncreamentRes;
573 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA
574 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA;
575 ext_ctrl[k++].value = pMpeg4Param->VopTimeIncreament;
577 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP;
578 ext_ctrl[k++].value = pMpeg4Param->FrameQp_B;
579 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
580 ext_ctrl[k++].value = 0;
581 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
582 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
583 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
584 ext_ctrl[k++].value = 1;
586 /* Initial parameters : Frame Skip */
587 switch (pInitParam->FrameSkip) {
588 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
589 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
590 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
592 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
593 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
594 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
597 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
598 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
599 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
603 ext_ctrls.count = MPEG4_CTRL_NUM;
607 case VIDEO_CODING_H263:
609 ExynosVideoEncH263Param *pH263Param = &pEncParam->codecParam.h263;
611 /* common parameters but id is depends on codec */
612 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP;
613 ext_ctrl[k++].value = pCommonParam->FrameQp;
614 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP;
615 ext_ctrl[k++].value = pCommonParam->FrameQp_P;
616 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP;
617 ext_ctrl[k++].value = pCommonParam->QSCodeMax;
618 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP;
619 ext_ctrl[k++].value = pCommonParam->QSCodeMin;
620 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
621 ext_ctrl[k++].value = pCommonParam->CBRPeriodRf;
623 /* H263 specific parameters */
624 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE
625 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE;
626 ext_ctrl[k++].value = pH263Param->FrameRate;
628 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
629 ext_ctrl[k++].value = 0;
630 ext_ctrl[k].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
631 ext_ctrl[k++].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
632 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
633 ext_ctrl[k++].value = 1;
635 /* Initial parameters : Frame Skip */
636 switch (pInitParam->FrameSkip) {
637 case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
638 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
639 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
641 case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
642 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
643 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
646 /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
647 ext_ctrl[k].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
648 ext_ctrl[k++].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
651 ext_ctrls.count = H263_CTRL_NUM;
656 ALOGE("[%s] Undefined codec type",__func__);
657 ret = VIDEO_ERROR_BADPARAM;
661 ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
662 ext_ctrls.controls = ext_ctrl;
664 if (exynos_v4l2_s_ext_ctrl(pCtx->hEnc, &ext_ctrls) != 0) {
665 ALOGE("%s: Failed to s_ext_ctrl", __func__);
666 ret = VIDEO_ERROR_APIFAIL;
675 * [Encoder OPS] Set Frame Tag
677 static ExynosVideoErrorType MFC_Encoder_Set_FrameTag(
681 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
682 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
685 ALOGE("%s: Video context info must be supplied", __func__);
686 ret = VIDEO_ERROR_BADPARAM;
689 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
690 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) {
691 ALOGE("%s: Failed to s_ctrl", __func__);
692 ret = VIDEO_ERROR_APIFAIL;
701 * [Encoder OPS] Get Frame Tag
703 static int MFC_Encoder_Get_FrameTag(void *pHandle)
705 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
706 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
711 ALOGE("%s: Video context info must be supplied", __func__);
714 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG
715 if (exynos_v4l2_g_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag) != 0) {
716 ALOGE("%s: Failed to g_ctrl", __func__);
717 ret = VIDEO_ERROR_APIFAIL;
726 * [Encoder OPS] Set Frame Type
728 static ExynosVideoErrorType MFC_Encoder_Set_FrameType(
730 ExynosVideoFrameType frameType)
732 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
733 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
736 ALOGE("%s: Video context info must be supplied", __func__);
737 ret = VIDEO_ERROR_BADPARAM;
742 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE, frameType) != 0) {
743 ALOGE("%s: Failed to s_ctrl", __func__);
744 ret = VIDEO_ERROR_APIFAIL;
754 * [Encoder OPS] Set Frame Rate
756 static ExynosVideoErrorType MFC_Encoder_Set_FrameRate(
760 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
761 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
764 ALOGE("%s: Video context info must be supplied", __func__);
765 ret = VIDEO_ERROR_BADPARAM;
768 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH
769 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH, frameRate) != 0) {
770 ALOGE("%s: Failed to s_ctrl", __func__);
771 ret = VIDEO_ERROR_APIFAIL;
781 * [Encoder OPS] Set Bit Rate
783 static ExynosVideoErrorType MFC_Encoder_Set_BitRate(
787 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
788 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
791 ALOGE("%s: Video context info must be supplied", __func__);
792 ret = VIDEO_ERROR_BADPARAM;
795 #ifdef V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH
796 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH, bitRate) != 0) {
797 ALOGE("%s: Failed to s_ctrl", __func__);
798 ret = VIDEO_ERROR_APIFAIL;
807 * [Encoder OPS] Set Frame Skip
809 static ExynosVideoErrorType MFC_Encoder_Set_FrameSkip(
813 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
814 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
817 ALOGE("%s: Video context info must be supplied", __func__);
818 ret = VIDEO_ERROR_BADPARAM;
822 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE, frameSkip) != 0) {
823 ALOGE("%s: Failed to s_ctrl", __func__);
824 ret = VIDEO_ERROR_APIFAIL;
833 * [Encoder OPS] Set IDR Period
835 static ExynosVideoErrorType MFC_Encoder_Set_IDRPeriod(
839 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
840 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
843 ALOGE("%s: Video context info must be supplied", __func__);
844 ret = VIDEO_ERROR_BADPARAM;
848 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, IDRPeriod) != 0) {
849 ALOGE("%s: Failed to s_ctrl", __func__);
850 ret = VIDEO_ERROR_APIFAIL;
859 * [Encoder OPS] Enable Prepend SPS and PPS to every IDR Frames
861 static ExynosVideoErrorType MFC_Encoder_Enable_PrependSpsPpsToIdr(void *pHandle)
863 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
864 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
867 ALOGE("%s: Video context info must be supplied", __func__);
868 ret = VIDEO_ERROR_BADPARAM;
871 #ifdef V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR
872 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR, 1) != 0) {
873 ALOGE("%s: Failed to s_ctrl", __func__);
874 ret = VIDEO_ERROR_APIFAIL;
883 * [Encoder Buffer OPS] Enable Cacheable (Input)
885 static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Inbuf(void *pHandle)
887 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
888 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
891 ALOGE("%s: Video context info must be supplied", __func__);
892 ret = VIDEO_ERROR_BADPARAM;
895 #ifdef V4L2_CID_CACHEABLE
896 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 2) != 0) {
897 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__);
898 ret = VIDEO_ERROR_APIFAIL;
907 * [Encoder Buffer OPS] Enable Cacheable (Output)
909 static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Outbuf(void *pHandle)
911 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
912 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
915 ALOGE("%s: Video context info must be supplied", __func__);
916 ret = VIDEO_ERROR_BADPARAM;
919 #ifdef V4L2_CID_CACHEABLE
920 if (exynos_v4l2_s_ctrl(pCtx->hEnc, V4L2_CID_CACHEABLE, 1) != 0) {
921 ALOGE("%s: Failed V4L2_CID_CACHEABLE", __func__);
922 ret = VIDEO_ERROR_APIFAIL;
931 * [Encoder Buffer OPS] Set Shareable Buffer (Input)
933 static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Inbuf(void *pHandle)
935 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
936 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
939 ALOGE("%s: Video context info must be supplied", __func__);
940 ret = VIDEO_ERROR_BADPARAM;
944 pCtx->bShareInbuf = VIDEO_TRUE;
951 * [Encoder Buffer OPS] Set Shareable Buffer (Output)
953 static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Outbuf(void *pHandle)
955 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
956 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
959 ALOGE("%s: Video context info must be supplied", __func__);
960 ret = VIDEO_ERROR_BADPARAM;
964 pCtx->bShareOutbuf = VIDEO_TRUE;
971 * [Encoder Buffer OPS] Get Buffer (Input)
973 static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Inbuf(
976 ExynosVideoBuffer **pBuffer)
978 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
979 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
982 ALOGE("%s: Video context info must be supplied", __func__);
984 ret = VIDEO_ERROR_NOBUFFERS;
988 if (pCtx->nInbufs <= nIndex) {
990 ret = VIDEO_ERROR_BADPARAM;
994 *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex];
1001 * [Encoder Buffer OPS] Get Buffer (Output)
1003 static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Outbuf(
1006 ExynosVideoBuffer **pBuffer)
1008 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1009 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1012 ALOGE("%s: Video context info must be supplied", __func__);
1014 ret = VIDEO_ERROR_NOBUFFERS;
1018 if (pCtx->nOutbufs <= nIndex) {
1020 ret = VIDEO_ERROR_BADPARAM;
1024 *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex];
1031 * [Encoder Buffer OPS] Set Geometry (Src)
1033 static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Inbuf(
1035 ExynosVideoGeometry *bufferConf)
1037 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1038 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1040 struct v4l2_format fmt;
1043 ALOGE("%s: Video context info must be supplied", __func__);
1044 ret = VIDEO_ERROR_BADPARAM;
1048 if (bufferConf == NULL) {
1049 ALOGE("%s: Buffer geometry must be supplied", __func__);
1050 ret = VIDEO_ERROR_BADPARAM;
1054 memset(&fmt, 0, sizeof(fmt));
1056 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1057 fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat);
1058 fmt.fmt.pix_mp.width = bufferConf->nFrameWidth;
1059 fmt.fmt.pix_mp.height = bufferConf->nFrameHeight;
1060 fmt.fmt.pix_mp.num_planes = VIDEO_ENCODER_INBUF_PLANES;
1063 if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) {
1064 ALOGE("%s: Failed to s_fmt", __func__);
1065 ret = VIDEO_ERROR_APIFAIL;
1069 memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry));
1076 * [Encoder Buffer OPS] Get Geometry (Src)
1078 static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Inbuf(
1080 ExynosVideoGeometry *bufferConf)
1082 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1083 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1085 struct v4l2_format fmt;
1088 ALOGE("%s: Video context info must be supplied", __func__);
1089 ret = VIDEO_ERROR_BADPARAM;
1093 if (bufferConf == NULL) {
1094 ALOGE("%s: Buffer geometry must be supplied", __func__);
1095 ret = VIDEO_ERROR_BADPARAM;
1099 memset(&fmt, 0, sizeof(fmt));
1101 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1102 if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) {
1103 ALOGE("%s: Failed to g_fmt", __func__);
1104 ret = VIDEO_ERROR_APIFAIL;
1108 bufferConf->nFrameHeight = fmt.fmt.pix_mp.width;
1109 bufferConf->nFrameHeight = fmt.fmt.pix_mp.height;
1110 bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1117 * [Encoder Buffer OPS] Set Geometry (Dst)
1119 static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Outbuf(
1121 ExynosVideoGeometry *bufferConf)
1123 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1124 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1126 struct v4l2_format fmt;
1129 ALOGE("%s: Video context info must be supplied", __func__);
1130 ret = VIDEO_ERROR_BADPARAM;
1134 if (bufferConf == NULL) {
1135 ALOGE("%s: Buffer geometry must be supplied", __func__);
1136 ret = VIDEO_ERROR_BADPARAM;
1140 memset(&fmt, 0, sizeof(fmt));
1142 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1143 fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat);
1144 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage;
1146 if (exynos_v4l2_s_fmt(pCtx->hEnc, &fmt) != 0) {
1147 ALOGE("%s: Failed to s_fmt", __func__);
1148 ret = VIDEO_ERROR_APIFAIL;
1152 memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry));
1159 * [Encoder Buffer OPS] Get Geometry (Dst)
1161 static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Outbuf(
1163 ExynosVideoGeometry *bufferConf)
1165 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1166 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1168 struct v4l2_format fmt;
1171 ALOGE("%s: Video context info must be supplied", __func__);
1172 ret = VIDEO_ERROR_BADPARAM;
1176 if (bufferConf == NULL) {
1177 ALOGE("%s: Buffer geometry must be supplied", __func__);
1178 ret = VIDEO_ERROR_BADPARAM;
1182 memset(&fmt, 0, sizeof(fmt));
1184 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1185 if (exynos_v4l2_g_fmt(pCtx->hEnc, &fmt) != 0) {
1186 ALOGE("%s: Failed to g_fmt", __func__);
1187 ret = VIDEO_ERROR_APIFAIL;
1192 bufferConf->nSizeImage = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
1199 * [Encoder Buffer OPS] Setup (Src)
1201 static ExynosVideoErrorType MFC_Encoder_Setup_Inbuf(
1203 unsigned int nBufferCount)
1205 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1206 ExynosVideoPlane *pVideoPlane = NULL;
1207 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1209 struct v4l2_requestbuffers req;
1210 struct v4l2_buffer buf;
1211 struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES];
1215 ALOGE("%s: Video context info must be supplied", __func__);
1216 ret = VIDEO_ERROR_BADPARAM;
1220 if (nBufferCount == 0) {
1221 ALOGE("%s: Buffer count must be greater than 0", __func__);
1222 ret = VIDEO_ERROR_BADPARAM;
1226 memset(&req, 0, sizeof(req));
1228 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1229 req.count = nBufferCount;
1231 if (pCtx->bShareInbuf == VIDEO_TRUE)
1232 req.memory = pCtx->nMemoryType;
1234 req.memory = V4L2_MEMORY_MMAP;
1236 if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) {
1237 ALOGE("Failed to require buffer");
1238 ret = VIDEO_ERROR_APIFAIL;
1242 pCtx->nInbufs = (int)req.count;
1244 pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
1245 if (pCtx->pInbuf == NULL) {
1246 ALOGE("%s: Failed to allocate input buffer context", __func__);
1247 ret = VIDEO_ERROR_NOMEM;
1250 memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs);
1252 memset(&buf, 0, sizeof(buf));
1254 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1255 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1256 buf.memory = V4L2_MEMORY_MMAP;
1257 buf.m.planes = planes;
1258 buf.length = VIDEO_ENCODER_INBUF_PLANES;
1260 for (i = 0; i < pCtx->nInbufs; i++) {
1262 if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) {
1263 ALOGE("%s: Failed to querybuf", __func__);
1264 ret = VIDEO_ERROR_APIFAIL;
1268 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
1269 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1270 pVideoPlane->addr = mmap(NULL,
1271 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1272 MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset);
1274 if (pVideoPlane->addr == MAP_FAILED) {
1275 ALOGE("%s: Failed to map", __func__);
1276 ret = VIDEO_ERROR_MAPFAIL;
1280 pVideoPlane->allocSize = buf.m.planes[j].length;
1281 pVideoPlane->dataSize = 0;
1284 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
1285 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1286 pCtx->pInbuf[i].bRegistered = VIDEO_TRUE;
1290 for (i = 0; i < pCtx->nInbufs; i++) {
1291 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry;
1292 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1293 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE;
1300 if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) {
1301 if (pCtx->bShareInbuf == VIDEO_FALSE) {
1302 for (i = 0; i < pCtx->nInbufs; i++) {
1303 for (j = 0; j < VIDEO_ENCODER_INBUF_PLANES; j++) {
1304 pVideoPlane = &pCtx->pInbuf[i].planes[j];
1305 if (pVideoPlane->addr == MAP_FAILED) {
1306 pVideoPlane->addr = NULL;
1310 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1322 * [Encoder Buffer OPS] Setup (Dst)
1324 static ExynosVideoErrorType MFC_Encoder_Setup_Outbuf(
1326 unsigned int nBufferCount)
1328 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1329 ExynosVideoPlane *pVideoPlane = NULL;
1330 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1332 struct v4l2_requestbuffers req;
1333 struct v4l2_buffer buf;
1334 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
1338 ALOGE("%s: Video context info must be supplied", __func__);
1339 ret = VIDEO_ERROR_BADPARAM;
1343 if (nBufferCount == 0) {
1344 ALOGE("%s: Buffer count must be greater than 0", __func__);
1345 ret = VIDEO_ERROR_BADPARAM;
1349 memset(&req, 0, sizeof(req));
1351 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1352 req.count = nBufferCount;
1354 if (pCtx->bShareOutbuf == VIDEO_TRUE)
1355 req.memory = pCtx->nMemoryType;
1357 req.memory = V4L2_MEMORY_MMAP;
1359 if (exynos_v4l2_reqbufs(pCtx->hEnc, &req) != 0) {
1360 ALOGE("%s: Failed to reqbuf", __func__);
1361 ret = VIDEO_ERROR_APIFAIL;
1365 pCtx->nOutbufs = req.count;
1367 pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1368 if (pCtx->pOutbuf == NULL) {
1369 ALOGE("%s: Failed to allocate output buffer context", __func__);
1370 ret = VIDEO_ERROR_NOMEM;
1373 memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs);
1375 memset(&buf, 0, sizeof(buf));
1377 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1378 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1379 buf.memory = V4L2_MEMORY_MMAP;
1380 buf.m.planes = planes;
1381 buf.length = VIDEO_ENCODER_OUTBUF_PLANES;
1383 for (i = 0; i < pCtx->nOutbufs; i++) {
1385 if (exynos_v4l2_querybuf(pCtx->hEnc, &buf) != 0) {
1386 ALOGE("%s: Failed to querybuf", __func__);
1387 ret = VIDEO_ERROR_APIFAIL;
1391 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
1392 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1393 pVideoPlane->addr = mmap(NULL,
1394 buf.m.planes[j].length, PROT_READ | PROT_WRITE,
1395 MAP_SHARED, pCtx->hEnc, buf.m.planes[j].m.mem_offset);
1397 if (pVideoPlane->addr == MAP_FAILED) {
1398 ALOGE("%s: Failed to map", __func__);
1399 ret = VIDEO_ERROR_MAPFAIL;
1403 pVideoPlane->allocSize = buf.m.planes[j].length;
1404 pVideoPlane->dataSize = 0;
1407 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1408 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1409 pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE;
1412 for (i = 0; i < pCtx->nOutbufs; i++ ) {
1413 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry;
1414 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1415 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE;
1422 if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) {
1423 if (pCtx->bShareOutbuf == VIDEO_FALSE) {
1424 for (i = 0; i < pCtx->nOutbufs; i++) {
1425 for (j = 0; j < VIDEO_ENCODER_OUTBUF_PLANES; j++) {
1426 pVideoPlane = &pCtx->pOutbuf[i].planes[j];
1427 if (pVideoPlane->addr == MAP_FAILED) {
1428 pVideoPlane->addr = NULL;
1432 munmap(pVideoPlane->addr, pVideoPlane->allocSize);
1437 free(pCtx->pOutbuf);
1444 * [Encoder Buffer OPS] Run (src)
1446 static ExynosVideoErrorType MFC_Encoder_Run_Inbuf(void *pHandle)
1448 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1449 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1452 ALOGE("%s: Video context info must be supplied", __func__);
1453 ret = VIDEO_ERROR_BADPARAM;
1457 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
1458 if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1459 ALOGE("%s: Failed to streamon for input buffer", __func__);
1460 ret = VIDEO_ERROR_APIFAIL;
1463 pCtx->bStreamonInbuf = VIDEO_TRUE;
1471 * [Encoder Buffer OPS] Run (Dst)
1473 static ExynosVideoErrorType MFC_Encoder_Run_Outbuf(void *pHandle)
1475 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1476 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1479 ALOGE("%s: Video context info must be supplied", __func__);
1480 ret = VIDEO_ERROR_BADPARAM;
1484 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
1485 if (exynos_v4l2_streamon(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1486 ALOGE("%s: Failed to streamon for output buffer", __func__);
1487 ret = VIDEO_ERROR_APIFAIL;
1490 pCtx->bStreamonOutbuf = VIDEO_TRUE;
1498 * [Encoder Buffer OPS] Stop (Src)
1500 static ExynosVideoErrorType MFC_Encoder_Stop_Inbuf(void *pHandle)
1502 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1503 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1507 ALOGE("%s: Video context info must be supplied", __func__);
1508 ret = VIDEO_ERROR_BADPARAM;
1512 if (pCtx->bStreamonInbuf == VIDEO_TRUE) {
1513 if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) {
1514 ALOGE("%s: Failed to streamoff for input buffer", __func__);
1515 ret = VIDEO_ERROR_APIFAIL;
1518 pCtx->bStreamonInbuf = VIDEO_FALSE;
1521 for (i = 0; i < pCtx->nInbufs; i++) {
1522 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
1530 * [Encoder Buffer OPS] Stop (Dst)
1532 static ExynosVideoErrorType MFC_Encoder_Stop_Outbuf(void *pHandle)
1534 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1535 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1539 ALOGE("%s: Video context info must be supplied", __func__);
1540 ret = VIDEO_ERROR_BADPARAM;
1544 if (pCtx->bStreamonOutbuf == VIDEO_TRUE) {
1545 if (exynos_v4l2_streamoff(pCtx->hEnc, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) {
1546 ALOGE("%s: Failed to streamoff for output buffer", __func__);
1547 ret = VIDEO_ERROR_APIFAIL;
1550 pCtx->bStreamonOutbuf = VIDEO_FALSE;
1553 for (i = 0; i < pCtx->nOutbufs; i++) {
1554 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
1562 * [Encoder Buffer OPS] Wait (Src)
1564 static ExynosVideoErrorType MFC_Encoder_Wait_Inbuf(void *pHandle)
1566 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1567 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1569 struct pollfd poll_events;
1573 ALOGE("%s: Video context info must be supplied", __func__);
1574 ret = VIDEO_ERROR_BADPARAM;
1578 poll_events.fd = pCtx->hEnc;
1579 poll_events.events = POLLOUT | POLLERR;
1580 poll_events.revents = 0;
1583 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
1584 if (poll_state > 0) {
1585 if (poll_events.revents & POLLOUT) {
1588 ALOGE("%s: Poll return error", __func__);
1589 ret = VIDEO_ERROR_POLL;
1592 } else if (poll_state < 0) {
1593 ALOGE("%s: Poll state error", __func__);
1594 ret = VIDEO_ERROR_POLL;
1597 } while (poll_state == 0);
1604 * [Encoder Buffer OPS] Wait (Dst)
1606 static ExynosVideoErrorType MFC_Encoder_Wait_Outbuf(void *pHandle)
1608 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1609 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1611 struct pollfd poll_events;
1613 int bframe_count = 0; // FIXME
1616 ALOGE("%s: Video context info must be supplied", __func__);
1617 ret = VIDEO_ERROR_BADPARAM;
1621 poll_events.fd = pCtx->hEnc;
1622 poll_events.events = POLLIN | POLLERR;
1623 poll_events.revents = 0;
1626 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
1627 if (poll_state > 0) {
1628 if (poll_events.revents & POLLIN) {
1631 ALOGE("%s: Poll return error", __func__);
1632 ret = VIDEO_ERROR_POLL;
1635 } else if (poll_state < 0) {
1636 ALOGE("%s: Poll state error", __func__);
1637 ret = VIDEO_ERROR_POLL;
1640 bframe_count++; // FIXME
1642 } while (poll_state == 0 && bframe_count < 5); // FIXME
1648 static ExynosVideoErrorType MFC_Encoder_Register_Inbuf(
1650 ExynosVideoPlane *planes,
1653 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1654 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1657 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_INBUF_PLANES)) {
1658 ALOGE("%s: input params must be supplied", __func__);
1659 ret = VIDEO_ERROR_BADPARAM;
1663 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1664 if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) {
1666 for (plane = 0; plane < nPlanes; plane++) {
1667 pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr;
1668 pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1669 pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd;
1670 ALOGV("%s: addr = 0x%x", __func__, pCtx->pInbuf[nIndex].planes[plane].addr);
1672 pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE;
1677 if (nIndex == pCtx->nInbufs) {
1678 ALOGE("%s: can not find non-registered input buffer", __func__);
1679 ret = VIDEO_ERROR_NOBUFFERS;
1686 static ExynosVideoErrorType MFC_Encoder_Register_Outbuf(
1688 ExynosVideoPlane *planes,
1691 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1692 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1695 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_ENCODER_OUTBUF_PLANES)) {
1696 ALOGE("%s: params must be supplied", __func__);
1697 ret = VIDEO_ERROR_BADPARAM;
1701 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1702 if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) {
1704 for (plane = 0; plane < nPlanes; plane++) {
1705 pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr;
1706 pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize;
1707 pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd;
1709 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE;
1714 if (nIndex == pCtx->nOutbufs) {
1715 ALOGE("%s: can not find non-registered output buffer", __func__);
1716 ret = VIDEO_ERROR_NOBUFFERS;
1723 static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
1725 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1726 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1730 ALOGE("%s: Video context info must be supplied", __func__);
1731 ret = VIDEO_ERROR_BADPARAM;
1735 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1736 pCtx->pInbuf[nIndex].planes[0].addr = NULL;
1737 pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE;
1744 static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
1746 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1747 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1751 ALOGE("%s: Video context info must be supplied", __func__);
1752 ret = VIDEO_ERROR_BADPARAM;
1756 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1757 pCtx->pOutbuf[nIndex].planes[0].addr = NULL;
1758 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE;
1766 * [Encoder Buffer OPS] Find (Input)
1768 static int MFC_Encoder_Find_Inbuf(
1770 unsigned char *pBuffer)
1772 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1776 ALOGE("%s: Video context info must be supplied", __func__);
1780 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
1781 if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) {
1782 if ((pBuffer == NULL) ||
1783 (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer))
1788 if (nIndex == pCtx->nInbufs)
1796 * [Encoder Buffer OPS] Find (Output)
1798 static int MFC_Encoder_Find_Outbuf(
1800 unsigned char *pBuffer)
1802 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1806 ALOGE("%s: Video context info must be supplied", __func__);
1810 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) {
1811 if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) {
1812 if ((pBuffer == NULL) ||
1813 (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer))
1818 if (nIndex == pCtx->nOutbufs)
1826 * [Encoder Buffer OPS] Enqueue (Input)
1828 static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf(
1830 unsigned char *pBuffer[],
1831 unsigned int dataSize[],
1835 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1836 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1837 pthread_mutex_t *pMutex = NULL;
1839 struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES];
1840 struct v4l2_buffer buf;
1844 ALOGE("%s: Video context info must be supplied", __func__);
1845 ret = VIDEO_ERROR_BADPARAM;
1849 if (VIDEO_ENCODER_INBUF_PLANES < nPlanes) {
1850 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1851 VIDEO_ENCODER_INBUF_PLANES, nPlanes);
1852 ret = VIDEO_ERROR_BADPARAM;
1856 memset(&planes,0,sizeof(planes));
1857 memset(&buf, 0, sizeof(buf));
1859 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1860 buf.m.planes = planes;
1861 buf.length = VIDEO_ENCODER_INBUF_PLANES;
1863 pMutex = (pthread_mutex_t*)pCtx->pInMutex;
1864 pthread_mutex_lock(pMutex);
1865 index = MFC_Encoder_Find_Inbuf(pCtx, pBuffer[0]);
1867 pthread_mutex_unlock(pMutex);
1868 ALOGE("%s: Failed to get index", __func__);
1869 ret = VIDEO_ERROR_NOBUFFERS;
1874 pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE;
1875 pthread_mutex_unlock(pMutex);
1877 if (pCtx->bShareInbuf == VIDEO_TRUE) {
1878 buf.memory = pCtx->nMemoryType;
1880 for (i = 0; i < nPlanes; i++) {
1881 /* V4L2_MEMORY_USERPTR */
1882 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1883 buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize;
1884 /* V4L2_MEMORY_DMABUF */
1885 #ifdef SLP_PLATFORM /* #ifdef USE_DMA_BUF */
1886 buf.m.planes[i].m.fd = pCtx->pInbuf[buf.index].planes[i].fd;
1887 buf.m.planes[i].length = 0; /* kernel give the length */
1889 buf.m.planes[i].bytesused = dataSize[i];
1892 buf.memory = V4L2_MEMORY_MMAP;
1893 for (i = 0; i < nPlanes; i++)
1894 buf.m.planes[i].bytesused = dataSize[i];
1897 ALOGE("call exynos_v4l2_qbuf(): %d", buf.m.planes[0].m.fd);
1898 if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) {
1899 ALOGE("%s: Failed to enqueue input buffer", __func__);
1900 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
1901 ret = VIDEO_ERROR_APIFAIL;
1905 pCtx->pInbuf[buf.index].pPrivate = pPrivate;
1912 * [Encoder Buffer OPS] Enqueue (Output)
1914 static ExynosVideoErrorType MFC_Encoder_Enqueue_Outbuf(
1916 unsigned char *pBuffer[],
1917 unsigned int dataSize[],
1921 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1922 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1923 pthread_mutex_t *pMutex = NULL;
1925 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
1926 struct v4l2_buffer buf;
1930 ALOGE("%s: Video context info must be supplied", __func__);
1931 ret = VIDEO_ERROR_BADPARAM;
1935 if (VIDEO_ENCODER_OUTBUF_PLANES < nPlanes) {
1936 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
1937 VIDEO_ENCODER_OUTBUF_PLANES, nPlanes);
1938 ret = VIDEO_ERROR_BADPARAM;
1942 memset(&buf, 0, sizeof(buf));
1944 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1945 buf.m.planes = planes;
1946 buf.length = VIDEO_ENCODER_OUTBUF_PLANES;
1948 pMutex = (pthread_mutex_t*)pCtx->pOutMutex;
1949 pthread_mutex_lock(pMutex);
1950 index = MFC_Encoder_Find_Outbuf(pCtx, pBuffer[0]);
1952 pthread_mutex_unlock(pMutex);
1953 ALOGE("%s: Failed to get index", __func__);
1954 ret = VIDEO_ERROR_NOBUFFERS;
1958 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE;
1959 pthread_mutex_unlock(pMutex);
1961 if (pCtx->bShareOutbuf == VIDEO_TRUE) {
1962 buf.memory = pCtx->nMemoryType;
1963 for (i = 0; i < nPlanes; i++) {
1964 /* V4L2_MEMORY_USERPTR */
1965 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i];
1966 buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize;
1967 /* V4L2_MEMORY_DMABUF */
1969 buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd;
1970 buf.m.planes[i].length = 0; /* kernel give the length */
1972 buf.m.planes[i].bytesused = dataSize[i];
1975 buf.memory = V4L2_MEMORY_MMAP;
1978 if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) {
1979 ALOGE("%s: Failed to enqueue output buffer", __func__);
1980 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE;
1981 ret = VIDEO_ERROR_APIFAIL;
1985 pCtx->pOutbuf[buf.index].pPrivate = pPrivate;
1992 * [Encoder Buffer OPS] Enqueue All (Output)
1994 static ExynosVideoErrorType MFC_Encoder_Enqueue_All_Outbuf(void *pHandle)
1996 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
1997 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
1999 unsigned char *pBuffer[VIDEO_BUFFER_MAX_PLANES] = {NULL, };
2000 unsigned int dataSize[VIDEO_BUFFER_MAX_PLANES] = {0, };
2005 ALOGE("%s: Video context info must be supplied", __func__);
2006 ret = VIDEO_ERROR_BADPARAM;
2010 for (i = 0; i < pCtx->nOutbufs; i++) {
2011 ret = MFC_Encoder_Enqueue_Outbuf(pCtx, pBuffer, dataSize, 1, NULL);
2012 if (ret != VIDEO_ERROR_NONE)
2021 * [Encoder Buffer OPS] Dequeue (Input)
2023 static ExynosVideoBuffer *MFC_Encoder_Dequeue_Inbuf(void *pHandle)
2025 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2026 ExynosVideoBuffer *pInbuf = NULL;
2028 struct v4l2_buffer buf;
2031 ALOGE("%s: Video context info must be supplied", __func__);
2035 if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
2040 memset(&buf, 0, sizeof(buf));
2042 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2044 if (pCtx->bShareInbuf == VIDEO_TRUE)
2045 buf.memory = pCtx->nMemoryType;
2047 buf.memory = V4L2_MEMORY_MMAP;
2049 if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) {
2054 pInbuf = &pCtx->pInbuf[buf.index];
2055 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
2062 * [Encoder Buffer OPS] Dequeue (Output)
2064 static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle)
2066 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2067 ExynosVideoBuffer *pOutbuf = NULL;
2069 struct v4l2_buffer buf;
2070 struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES];
2074 ALOGE("%s: Video context info must be supplied", __func__);
2078 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) {
2083 memset(&buf, 0, sizeof(buf));
2085 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2086 buf.m.planes = planes;
2089 if (pCtx->bShareOutbuf == VIDEO_TRUE)
2090 buf.memory = pCtx->nMemoryType;
2092 buf.memory = V4L2_MEMORY_MMAP;
2094 /* no error case for output buffer dequeue in encoder */
2095 if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) {
2099 pOutbuf = &pCtx->pOutbuf[buf.index];
2100 pOutbuf->planes[0].dataSize = buf.m.planes[0].bytesused;
2102 switch (buf.flags & (0x7 << 3)) {
2103 case V4L2_BUF_FLAG_KEYFRAME:
2104 pOutbuf->frameType = VIDEO_FRAME_I;
2106 case V4L2_BUF_FLAG_PFRAME:
2107 pOutbuf->frameType = VIDEO_FRAME_P;
2109 case V4L2_BUF_FLAG_BFRAME:
2110 pOutbuf->frameType = VIDEO_FRAME_B;
2113 ALOGI("%s: encoded frame type is = %d",__func__, (buf.flags & (0x7 << 3)));
2114 pOutbuf->frameType = VIDEO_FRAME_OTHERS;
2118 pOutbuf->bQueued = VIDEO_FALSE;
2124 static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Inbuf(void *pHandle)
2126 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2127 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2131 ALOGE("%s: Video context info must be supplied", __func__);
2132 ret = VIDEO_ERROR_BADPARAM;
2136 for (i = 0; i < pCtx->nInbufs; i++) {
2137 pCtx->pInbuf[i].bQueued = VIDEO_FALSE;
2144 static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Outbuf(void *pHandle)
2146 ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
2147 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2151 ALOGE("%s: Video context info must be supplied", __func__);
2152 ret = VIDEO_ERROR_BADPARAM;
2156 for (i = 0; i < pCtx->nOutbufs; i++) {
2157 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE;
2165 * [Encoder OPS] Common
2167 static ExynosVideoEncOps defEncOps = {
2169 .Init = MFC_Encoder_Init,
2170 .Finalize = MFC_Encoder_Finalize,
2171 .Set_EncParam = MFC_Encoder_Set_EncParam,
2172 .Set_FrameType = MFC_Encoder_Set_FrameType,
2173 .Set_FrameRate = MFC_Encoder_Set_FrameRate,
2174 .Set_BitRate = MFC_Encoder_Set_BitRate,
2175 .Set_FrameSkip = MFC_Encoder_Set_FrameSkip,
2176 .Set_IDRPeriod = MFC_Encoder_Set_IDRPeriod,
2177 .Set_FrameTag = MFC_Encoder_Set_FrameTag,
2178 .Get_FrameTag = MFC_Encoder_Get_FrameTag,
2179 .Enable_PrependSpsPpsToIdr = MFC_Encoder_Enable_PrependSpsPpsToIdr,
2183 * [Encoder Buffer OPS] Input
2185 static ExynosVideoEncBufferOps defInbufOps = {
2187 .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Inbuf,
2188 .Set_Shareable = MFC_Encoder_Set_Shareable_Inbuf,
2189 .Get_Buffer = MFC_Encoder_Get_Buffer_Inbuf,
2190 .Set_Geometry = MFC_Encoder_Set_Geometry_Inbuf,
2191 .Get_Geometry = MFC_Encoder_Get_Geometry_Inbuf,
2192 .Setup = MFC_Encoder_Setup_Inbuf,
2193 .Run = MFC_Encoder_Run_Inbuf,
2194 .Stop = MFC_Encoder_Stop_Inbuf,
2195 .Enqueue = MFC_Encoder_Enqueue_Inbuf,
2196 .Enqueue_All = NULL,
2197 .Dequeue = MFC_Encoder_Dequeue_Inbuf,
2198 .Register = MFC_Encoder_Register_Inbuf,
2199 .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Inbuf,
2200 .Clear_Queue = MFC_Encoder_Clear_Queued_Inbuf,
2204 * [Encoder Buffer OPS] Output
2206 static ExynosVideoEncBufferOps defOutbufOps = {
2208 .Enable_Cacheable = MFC_Encoder_Enable_Cacheable_Outbuf,
2209 .Set_Shareable = MFC_Encoder_Set_Shareable_Outbuf,
2210 .Get_Buffer = MFC_Encoder_Get_Buffer_Outbuf,
2211 .Set_Geometry = MFC_Encoder_Set_Geometry_Outbuf,
2212 .Get_Geometry = MFC_Encoder_Get_Geometry_Outbuf,
2213 .Setup = MFC_Encoder_Setup_Outbuf,
2214 .Run = MFC_Encoder_Run_Outbuf,
2215 .Stop = MFC_Encoder_Stop_Outbuf,
2216 .Enqueue = MFC_Encoder_Enqueue_Outbuf,
2217 .Enqueue_All = NULL,
2218 .Dequeue = MFC_Encoder_Dequeue_Outbuf,
2219 .Register = MFC_Encoder_Register_Outbuf,
2220 .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Outbuf,
2221 .Clear_Queue = MFC_Encoder_Clear_Queued_Outbuf,
2224 int Exynos_Video_Register_Encoder(
2225 ExynosVideoEncOps *pEncOps,
2226 ExynosVideoEncBufferOps *pInbufOps,
2227 ExynosVideoEncBufferOps *pOutbufOps)
2229 ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
2231 if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
2232 ret = VIDEO_ERROR_BADPARAM;
2236 defEncOps.nSize = sizeof(defEncOps);
2237 defInbufOps.nSize = sizeof(defInbufOps);
2238 defOutbufOps.nSize = sizeof(defOutbufOps);
2240 memcpy((char *)pEncOps + sizeof(pEncOps->nSize), (char *)&defEncOps + sizeof(defEncOps.nSize),
2241 pEncOps->nSize - sizeof(pEncOps->nSize));
2243 memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
2244 pInbufOps->nSize - sizeof(pInbufOps->nSize));
2246 memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
2247 pOutbufOps->nSize - sizeof(pOutbufOps->nSize));