summaryrefslogtreecommitdiffstats
path: root/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2
diff options
context:
space:
mode:
Diffstat (limited to 'exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2')
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/Android.mk39
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c1740
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c1506
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h431
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h79
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h588
6 files changed, 4383 insertions, 0 deletions
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/Android.mk
new file mode 100644
index 0000000..89f3e84
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/Android.mk
@@ -0,0 +1,39 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_COPY_HEADERS_TO := libsecmm
+LOCAL_COPY_HEADERS := \
+ include/mfc_errno.h \
+ include/mfc_interface.h \
+ include/SsbSipMfcApi.h
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ dec/src/SsbSipMfcDecAPI.c \
+ enc/src/SsbSipMfcEncAPI.c
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/include \
+ $(BOARD_HAL_PATH)/include
+
+LOCAL_MODULE := libsecmfcapi
+
+LOCAL_PRELINK_MODULE := false
+
+ifeq ($(BOARD_USE_S3D_SUPPORT), true)
+LOCAL_CFLAGS += -DS3D_SUPPORT
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES :=
+LOCAL_SHARED_LIBRARIES := liblog
+
+#ifeq ($(BOARD_USE_V4L2_ION),true)
+#LOCAL_CFLAGS += -DUSE_ION
+#LOCAL_SHARED_LIBRARIES += libion
+#endif
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c
new file mode 100644
index 0000000..fb04587
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c
@@ -0,0 +1,1740 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <sys/poll.h>
+#include "videodev2.h"
+
+#include "mfc_interface.h"
+#include "SsbSipMfcApi.h"
+#ifdef USE_ION
+#include "ion.h"
+#endif
+
+/* #define LOG_NDEBUG 0 */
+#define LOG_TAG "MFC_DEC_APP"
+#include <utils/Log.h>
+
+/*#define CRC_ENABLE
+#define SLICE_MODE_ENABLE */
+#define POLL_DEC_WAIT_TIMEOUT 25
+
+#define USR_DATA_START_CODE (0x000001B2)
+#define VOP_START_CODE (0x000001B6)
+#define MP4_START_CODE (0x000001)
+
+#define DEFAULT_NUMBER_OF_EXTRA_DPB 5
+#define CLEAR(x) memset (&(x), 0, sizeof(x))
+#ifdef S3D_SUPPORT
+#define OPERATE_BIT(x, mask, shift) ((x & (mask << shift)) >> shift)
+#define FRAME_PACK_SEI_INFO_NUM 4
+#endif
+
+enum {
+ NV12MT_FMT = 0,
+ NV12M_FMT,
+ NV21M_FMT,
+};
+
+static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME;
+static int mfc_dev_node = 6;
+
+int read_header_data(void *openHandle);
+int init_mfc_output_stream(void *openHandle);
+int isBreak_loop(void *openHandle);
+
+int v4l2_mfc_querycap(int fd)
+{
+ struct v4l2_capability cap;
+ int ret;
+
+ CLEAR(cap);
+
+ ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QUERYCAP failed", __func__);
+ return ret;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
+ LOGE("[%s] Device does not support capture", __func__);
+ return -1;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
+ LOGE("[%s] Device does not support output", __func__);
+ return -1;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
+ LOGE("[%s] Device does not support streaming", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+int v4l2_mfc_s_fmt(int fd, enum v4l2_buf_type type,
+ int pixelformat, unsigned int sizeimage, int width, int height)
+{
+ int ret;
+ struct v4l2_format fmt;
+
+ CLEAR(fmt);
+
+ fmt.type = type;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ switch (pixelformat) {
+ case H264_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+ break;
+ case MPEG4_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4;
+ break;
+ case H263_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263;
+ break;
+ case XVID_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_XVID;
+ break;
+ case MPEG2_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG12;
+ break;
+ case FIMV1_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV1;
+ fmt.fmt.pix_mp.width = width;
+ fmt.fmt.pix_mp.height = height;
+ break;
+ case FIMV2_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV2;
+ break;
+ case FIMV3_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV3;
+ break;
+ case FIMV4_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_FIMV4;
+ break;
+ case VC1_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1;
+ break;
+ case VC1RCV_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VC1_RCV;
+ break;
+#if defined (MFC6x_VERSION)
+ case VP8_DEC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_VP8;
+ break;
+#endif
+ default:
+ LOGE("[%s] Does NOT support the codec type (%d)", __func__, pixelformat);
+ return -1;
+ }
+ fmt.fmt.pix_mp.plane_fmt[0].sizeimage = sizeimage;
+ } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ switch (pixelformat) {
+ case NV12MT_FMT:
+#if defined (MFC6x_VERSION)
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
+#else
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT;
+#endif
+ break;
+ case NV12M_FMT:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
+ break;
+ case NV21M_FMT:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV21M;
+ break;
+ default:
+ LOGE("[%s] Does NOT support the pixel format (%d)", __func__, pixelformat);
+ return -1;
+ }
+ } else {
+ LOGE("[%s] Wrong buffer type", __func__);
+ return -1;
+ }
+
+ ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
+
+ return ret;
+}
+
+int v4l2_mfc_reqbufs(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, int *buf_cnt)
+{
+ struct v4l2_requestbuffers reqbuf;
+ int ret;
+
+ CLEAR(reqbuf);
+
+ reqbuf.type = type;
+ reqbuf.memory = memory;
+ reqbuf.count = *buf_cnt;
+
+ ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf);
+ *buf_cnt = reqbuf.count;
+
+ return ret;
+}
+
+int v4l2_mfc_querybuf(int fd, struct v4l2_buffer *buf, enum v4l2_buf_type type,
+ enum v4l2_memory memory, int index, struct v4l2_plane *planes)
+{
+ int length = -1, ret;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ length = 1;
+ else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ length = 2;
+
+ CLEAR(*buf);
+ buf->type = type;
+ buf->memory = memory;
+ buf->index = index;
+ buf->m.planes = planes;
+ buf->length = length;
+
+ ret = ioctl(fd, VIDIOC_QUERYBUF, buf);
+
+ return ret;
+}
+
+int v4l2_mfc_streamon(int fd, enum v4l2_buf_type type)
+{
+ int ret;
+
+ ret = ioctl(fd, VIDIOC_STREAMON, &type);
+
+ return ret;
+}
+
+int v4l2_mfc_streamoff(int fd, enum v4l2_buf_type type)
+{
+ int ret;
+
+ ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
+
+ return ret;
+}
+
+int v4l2_mfc_s_ctrl(int fd, int id, int value)
+{
+ struct v4l2_control ctrl;
+ int ret;
+
+ CLEAR(ctrl);
+ ctrl.id = id;
+ ctrl.value = value;
+
+ ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
+
+ return ret;
+}
+
+int v4l2_mfc_g_ctrl(int fd, int id, int *value)
+{
+ struct v4l2_control ctrl;
+ int ret;
+
+ CLEAR(ctrl);
+ ctrl.id = id;
+
+ ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl);
+ *value = ctrl.value;
+
+ return ret;
+}
+
+#ifdef S3D_SUPPORT
+int v4l2_mfc_ext_g_ctrl(int fd, SSBSIP_MFC_DEC_CONF conf_type, void *value)
+{
+ struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM];
+ struct v4l2_ext_controls ext_ctrls;
+ struct mfc_frame_pack_sei_info *sei_info;
+ int ret, i;
+
+ ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_CODEC;
+
+ switch (conf_type) {
+ case MFC_DEC_GETCONF_FRAME_PACKING:
+ sei_info = (struct mfc_frame_pack_sei_info *)value;
+ for (i=0; i<FRAME_PACK_SEI_INFO_NUM; i++)
+ CLEAR(ext_ctrl[i]);
+
+ ext_ctrls.count = FRAME_PACK_SEI_INFO_NUM;
+ ext_ctrls.controls = ext_ctrl;
+ ext_ctrl[0].id = V4L2_CID_CODEC_FRAME_PACK_SEI_AVAIL;
+ ext_ctrl[1].id = V4L2_CID_CODEC_FRAME_PACK_ARRGMENT_ID;
+ ext_ctrl[2].id = V4L2_CID_CODEC_FRAME_PACK_SEI_INFO;
+ ext_ctrl[3].id = V4L2_CID_CODEC_FRAME_PACK_GRID_POS;
+
+ ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, &ext_ctrls);
+
+ sei_info->sei_avail = ext_ctrl[0].value;
+ sei_info->arrgment_id = ext_ctrl[1].value;
+ sei_info->sei_info = ext_ctrl[2].value;
+ sei_info->grid_pos = ext_ctrl[3].value;
+ break;
+ }
+
+ return ret;
+}
+#endif
+
+int v4l2_mfc_qbuf(int fd, struct v4l2_buffer *qbuf, enum v4l2_buf_type type,
+ enum v4l2_memory memory, int index,
+ struct v4l2_plane *planes, int frame_length)
+{
+ int ret, length = 0;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ CLEAR(*qbuf);
+ length = 1;
+ } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ length = 2;
+ }
+
+ qbuf->type = type;
+ qbuf->memory = memory;
+ qbuf->index = index;
+ qbuf->m.planes = planes;
+ qbuf->length = length;
+ qbuf->m.planes[0].bytesused = frame_length;
+
+ ret = ioctl(fd, VIDIOC_QBUF, qbuf);
+
+ return ret;
+}
+
+int v4l2_mfc_dqbuf(int fd, struct v4l2_buffer *dqbuf, enum v4l2_buf_type type,
+ enum v4l2_memory memory)
+{
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+ int ret, length = 0;
+
+ CLEAR(*dqbuf);
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ length = 1;
+ else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ length = 2;
+
+ dqbuf->type = type;
+ dqbuf->memory = memory;
+ dqbuf->m.planes = planes;
+ dqbuf->length = length;
+
+ ret = ioctl(fd, VIDIOC_DQBUF, dqbuf);
+
+ return ret;
+}
+
+int v4l2_mfc_g_fmt(int fd, struct v4l2_format *fmt, enum v4l2_buf_type type)
+{
+ int ret;
+
+ CLEAR(*fmt);
+ fmt->type = type;
+ ret = ioctl(fd, VIDIOC_G_FMT, fmt);
+
+ return ret;
+}
+
+int v4l2_mfc_g_crop(int fd, struct v4l2_crop *crop, enum v4l2_buf_type type)
+{
+ int ret;
+
+ CLEAR(*crop);
+ crop->type = type;
+ ret = ioctl(fd, VIDIOC_G_CROP, crop);
+
+ return ret;
+}
+
+int v4l2_mfc_poll(int fd, int *revents, int timeout)
+{
+ struct pollfd poll_events;
+ int ret;
+
+ poll_events.fd = fd;
+ poll_events.events = POLLOUT | POLLERR;
+ poll_events.revents = 0;
+
+ ret = poll((struct pollfd*)&poll_events, 1, timeout);
+ *revents = poll_events.revents;
+
+ return ret;
+}
+
+static void getAByte(char *buff, int *code)
+{
+ int byte;
+
+ *code = (*code << 8);
+ byte = (int)*buff;
+ byte &= 0xFF;
+ *code |= byte;
+}
+
+static int isPBPacked(_MFCLIB *pCtx, int Frameleng)
+{
+ char *strmBuffer = NULL;
+ int startCode = 0xFFFFFFFF;
+ int leng_idx = 1;
+
+ strmBuffer = (char*)pCtx->virStrmBuf;
+
+ while (1) {
+ while (startCode != USR_DATA_START_CODE) {
+ if ((startCode == VOP_START_CODE) || (leng_idx == Frameleng)) {
+ LOGI("[%s] VOP START Found !!.....return",__func__);
+ LOGW("[%s] Non Packed PB",__func__);
+ return 0;
+ }
+ getAByte(strmBuffer, &startCode);
+ LOGV(">> StartCode = 0x%08x <<\n", startCode);
+ strmBuffer++;
+ leng_idx++;
+ }
+ LOGI("[%s] User Data Found !!",__func__);
+
+ do {
+ if (*strmBuffer == 'p') {
+ LOGW("[%s] Packed PB",__func__);
+ return 1;
+ }
+ getAByte(strmBuffer, &startCode);
+ strmBuffer++; leng_idx++;
+ } while ((leng_idx <= Frameleng) && ((startCode >> 8) != MP4_START_CODE));
+
+ if (leng_idx > Frameleng)
+ break;
+ }
+
+ LOGW("[%s] Non Packed PB",__func__);
+
+ return 0;
+}
+
+static void getMFCName(char *devicename, int size)
+{
+ snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node);
+}
+
+void SsbSipMfcDecSetMFCNode(int devicenode)
+{
+ mfc_dev_node = devicenode;
+}
+
+void SsbSipMfcDecSetMFCName(char *devicename)
+{
+ mfc_dev_name = devicename;
+}
+
+void *SsbSipMfcDecOpen(void)
+{
+ int hMFCOpen;
+ _MFCLIB *pCTX;
+ char mfc_dev_name[64];
+
+ int ret;
+ int req_count;
+ unsigned int i, j;
+
+ struct v4l2_buffer buf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+
+ LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR);
+
+ pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
+ if (pCTX == NULL) {
+ LOGE("[%s] malloc failed.",__func__);
+ return NULL;
+ }
+
+ memset(pCTX, 0, sizeof(_MFCLIB));
+
+ getMFCName(mfc_dev_name, 64);
+ LOGI("[%s] dev name is %s",__func__,mfc_dev_name);
+
+ if (access(mfc_dev_name, F_OK) != 0) {
+ LOGE("[%s] MFC device node not exists",__func__);
+ goto error_case1;
+ }
+
+ hMFCOpen = open(mfc_dev_name, O_RDWR|O_NONBLOCK, 0);
+ if (hMFCOpen < 0) {
+ LOGE("[%s] Failed to open MFC device",__func__);
+ goto error_case1;
+ }
+
+ pCTX->hMFC = hMFCOpen;
+
+ ret = v4l2_mfc_querycap(pCTX->hMFC);
+ if (ret != 0) {
+ LOGE("[%s] QUERYCAP failed", __func__);
+ goto error_case2;
+ }
+
+ pCTX->inter_buff_status = MFC_USE_NONE;
+ ret = v4l2_mfc_s_fmt(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ H264_DEC, MAX_DECODER_INPUT_BUFFER_SIZE, 0, 0);
+ if (ret != 0) {
+ LOGE("[%s] S_FMT failed",__func__);
+ goto error_case2;
+ }
+
+ pCTX->v4l2_dec.mfc_src_bufs_len = MAX_DECODER_INPUT_BUFFER_SIZE;
+
+ req_count = MFC_DEC_NUM_SRC_BUFS;
+ ret = v4l2_mfc_reqbufs(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ V4L2_MEMORY_MMAP, &req_count);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_REQBUFS failed",__func__);
+ goto error_case2;
+ }
+
+ pCTX->v4l2_dec.mfc_num_src_bufs = req_count;
+
+ for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; ++i) {
+ ret = v4l2_mfc_querybuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ V4L2_MEMORY_MMAP, i, planes);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QUERYBUF failed",__func__);
+ goto error_case3;
+ }
+
+ pCTX->v4l2_dec.mfc_src_bufs[i] = mmap(NULL, buf.m.planes[0].length,
+ PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset);
+ if (pCTX->v4l2_dec.mfc_src_bufs[i] == MAP_FAILED) {
+ LOGE("[%s] mmap failed (%d)",__func__,i);
+ goto error_case3;
+ }
+ }
+ pCTX->inter_buff_status |= MFC_USE_STRM_BUFF;
+
+ /* set extra DPB size to 5 as default for optimal performce (heuristic method) */
+ pCTX->dec_numextradpb = DEFAULT_NUMBER_OF_EXTRA_DPB;
+
+ pCTX->v4l2_dec.bBeingFinalized = 0;
+ pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED;
+
+ pCTX->cacheablebuffer = NO_CACHE;
+
+ for (i = 0; i<MFC_DEC_NUM_SRC_BUFS; i++)
+ pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_DEQUEUED;
+
+ pCTX->v4l2_dec.beingUsedIndex = 0;
+
+ return (void *) pCTX;
+
+error_case3:
+ for (j = 0; j < i; j++)
+ munmap(pCTX->v4l2_dec.mfc_src_bufs[j], pCTX->v4l2_dec.mfc_src_bufs_len);
+error_case2:
+ close(pCTX->hMFC);
+error_case1:
+ free(pCTX);
+
+ return NULL;
+}
+
+void *SsbSipMfcDecOpenExt(void *value)
+{
+ _MFCLIB *pCTX;
+
+ pCTX = SsbSipMfcDecOpen();
+
+ if (pCTX == NULL)
+ return NULL;
+
+ if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) {
+ pCTX->cacheablebuffer = NO_CACHE;
+ LOGI("[%s] non cacheable buffer",__func__);
+ } else {
+ pCTX->cacheablebuffer = CACHE;
+ LOGI("[%s] cacheable buffer",__func__);
+ }
+
+ return (void *)pCTX;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle)
+{
+ int ret, i;
+ _MFCLIB *pCTX;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ if (pCTX->inter_buff_status & MFC_USE_DST_STREAMON) {
+ ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__);
+ return MFC_RET_CLOSE_FAIL;
+ }
+ pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON);
+ }
+
+ if (pCTX->inter_buff_status & MFC_USE_SRC_STREAMON) {
+ ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_STREAMOFF failed (source buffers)",__func__);
+ return MFC_RET_CLOSE_FAIL;
+ }
+ pCTX->inter_buff_status &= ~(MFC_USE_SRC_STREAMON);
+ }
+
+ if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) {
+ for (i = 0; i < pCTX->v4l2_dec.mfc_num_src_bufs; i++)
+ munmap(pCTX->v4l2_dec.mfc_src_bufs[i], pCTX->v4l2_dec.mfc_src_bufs_len);
+ pCTX->inter_buff_status &= ~(MFC_USE_STRM_BUFF);
+ }
+
+ if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) {
+ for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; i++) {
+ munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]);
+ munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]);
+ }
+ pCTX->inter_buff_status &= ~(MFC_USE_YUV_BUFF);
+ }
+
+#ifdef USE_ION
+ ion_client_destroy(pCTX->ion_fd);
+#endif
+ close(pCTX->hMFC);
+ free(pCTX);
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng)
+{
+ int packedPB = 0;
+ _MFCLIB *pCTX;
+ int ret;
+
+ int width, height;
+ int ctrl_value;
+
+ struct v4l2_buffer buf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+
+ int poll_state, poll_revents;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ pCTX->codecType = codec_type;
+
+ if ((pCTX->codecType == MPEG4_DEC) || (pCTX->codecType == XVID_DEC) ||
+ (pCTX->codecType == FIMV1_DEC) || (pCTX->codecType == FIMV2_DEC) ||
+ (pCTX->codecType == FIMV3_DEC) || (pCTX->codecType == FIMV4_DEC))
+ packedPB = isPBPacked(pCTX, Frameleng);
+
+ if (pCTX->codecType == FIMV1_DEC) {
+ width = pCTX->fimv1_res.width;
+ height = pCTX->fimv1_res.height;
+ } else {
+ width = 0;
+ height = 0;
+ }
+ ret = v4l2_mfc_s_fmt(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, pCTX->codecType,
+ MAX_DECODER_INPUT_BUFFER_SIZE, width, height);
+ if (ret != 0) {
+ LOGE("[%s] S_FMT failed", __func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ /* Set default destination format as NV12MT */
+ ret = v4l2_mfc_s_fmt(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, NV12MT_FMT,
+ 0, width, height);
+ if (ret != 0) {
+ LOGE("[%s] S_FMT failed",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ /* PackedPB should be set after VIDIOC_S_FMT */
+ if (packedPB) {
+ ret = v4l2_mfc_s_ctrl(pCTX->hMFC, V4L2_CID_CODEC_PACKED_PB, 1);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_S_CTRL failed of PACKED_PB\n", __func__);
+ return MFC_RET_DEC_SET_CONF_FAIL;
+ }
+ }
+
+ ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, Frameleng);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ /* Processing the header requires running streamon
+ on OUTPUT queue */
+ ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_STREAMON failed",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+ pCTX->inter_buff_status |= MFC_USE_SRC_STREAMON;
+
+ ret = read_header_data(pCTX);
+ if (ret != 0)
+ goto error_case1;
+
+ /* cacheable buffer */
+ if (pCTX->cacheablebuffer == NO_CACHE)
+ ctrl_value = 0;
+ else
+ ctrl_value = 1;
+
+ ret = v4l2_mfc_s_ctrl(pCTX->hMFC, V4L2_CID_CACHEABLE, ctrl_value);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE", __func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+#ifdef USE_ION
+ pCTX->ion_fd = ion_client_create();
+ if (pCTX->ion_fd < 3) {
+ LOGE("[%s] Failed to get ion_fd : %d", __func__, pCTX->ion_fd);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+#endif
+
+ ret = init_mfc_output_stream(pCTX);
+ if (ret != 0)
+ goto error_case1;
+
+ ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)", __func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+ pCTX->inter_buff_status |= MFC_USE_DST_STREAMON;
+
+ do {
+ poll_state = v4l2_mfc_poll(pCTX->hMFC, &poll_revents, POLL_DEC_WAIT_TIMEOUT);
+ if (poll_state > 0) {
+ if (poll_revents & POLLOUT) {
+ ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP);
+ if (ret == 0)
+ break;
+ } else if (poll_revents & POLLERR) {
+ LOGE("[%s] POLLERR\n", __func__);
+ return MFC_GETOUTBUF_STATUS_NULL;
+ } else {
+ LOGE("[%s] poll() returns 0x%x\n", __func__, poll_revents);
+ return MFC_GETOUTBUF_STATUS_NULL;
+ }
+ } else if (poll_state < 0) {
+ return MFC_GETOUTBUF_STATUS_NULL;
+ }
+ } while (poll_state == 0);
+
+ return MFC_RET_OK;
+
+error_case1:
+ SsbSipMfcDecClose(openHandle);
+ return ret;
+}
+
+int read_header_data(void *openHandle)
+{
+ struct v4l2_format fmt;
+ struct v4l2_crop crop;
+ struct v4l2_pix_format_mplane pix_mp;
+ int ctrl_value;
+ int ret;
+
+ _MFCLIB *pCTX;
+ pCTX = (_MFCLIB *) openHandle;
+
+ ret = v4l2_mfc_g_fmt(pCTX->hMFC, &fmt, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_FMT failed",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case;
+ }
+
+ pix_mp = fmt.fmt.pix_mp;
+ pCTX->decOutInfo.buf_width = pix_mp.plane_fmt[0].bytesperline;
+ pCTX->decOutInfo.buf_height =
+ pix_mp.plane_fmt[0].sizeimage / pix_mp.plane_fmt[0].bytesperline;
+
+ pCTX->decOutInfo.img_width = pix_mp.width;
+ pCTX->decOutInfo.img_height = pix_mp.height;
+
+ ret = v4l2_mfc_g_crop(pCTX->hMFC, &crop, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CROP failed",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case;
+ }
+
+ pCTX->decOutInfo.crop_left_offset = crop.c.left;
+ pCTX->decOutInfo.crop_top_offset = crop.c.top;
+ pCTX->decOutInfo.crop_right_offset =
+ pix_mp.width - crop.c.width - crop.c.left;
+ pCTX->decOutInfo.crop_bottom_offset =
+ pix_mp.height - crop.c.height - crop.c.top;
+
+ ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_REQ_NUM_BUFS, &ctrl_value);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case;
+ }
+
+ pCTX->v4l2_dec.mfc_num_dst_bufs = ctrl_value + pCTX->dec_numextradpb;
+
+ LOGV("[%s] Num of allocated buffers: %d\n",__func__, pCTX->v4l2_dec.mfc_num_dst_bufs);
+
+ return 0;
+
+error_case:
+ return ret;
+ }
+
+/* Initialize output stream of MFC */
+int init_mfc_output_stream(void *openHandle)
+{
+ struct v4l2_buffer buf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+ int ret;
+ int i, j;
+ _MFCLIB *pCTX;
+ pCTX = (_MFCLIB *) openHandle;
+
+ ret = v4l2_mfc_reqbufs(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ V4L2_MEMORY_MMAP, (int *)&pCTX->v4l2_dec.mfc_num_dst_bufs);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_REQBUFS failed (destination buffers)",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) {
+ ret = v4l2_mfc_querybuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ V4L2_MEMORY_MMAP, i, planes);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QUERYBUF failed (destination buffers)",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ pCTX->v4l2_dec.mfc_dst_bufs_len[0] = buf.m.planes[0].length;
+ pCTX->v4l2_dec.mfc_dst_bufs_len[1] = buf.m.planes[1].length;
+
+ pCTX->v4l2_dec.mfc_dst_phys[i][0] = buf.m.planes[0].cookie;
+ pCTX->v4l2_dec.mfc_dst_phys[i][1] = buf.m.planes[1].cookie;
+
+#ifdef USE_ION
+ pCTX->dst_ion_fd[i][0] = (int)buf.m.planes[0].share;
+ pCTX->dst_ion_fd[i][1] = (int)buf.m.planes[1].share;
+
+ pCTX->v4l2_dec.mfc_dst_bufs[i][0] =
+ ion_map(pCTX->dst_ion_fd[i][0],pCTX->v4l2_dec.mfc_dst_bufs_len[0],0);
+ pCTX->v4l2_dec.mfc_dst_bufs[i][1] =
+ ion_map(pCTX->dst_ion_fd[i][1],pCTX->v4l2_dec.mfc_dst_bufs_len[1],0);
+ if (pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED ||
+ pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED)
+ goto error_case2;
+#else
+ pCTX->v4l2_dec.mfc_dst_bufs[i][0] = mmap(NULL, buf.m.planes[0].length,
+ PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset);
+ if (pCTX->v4l2_dec.mfc_dst_bufs[i][0] == MAP_FAILED) {
+ LOGE("[%s] mmap failed (destination buffers (Y))",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case2;
+ }
+
+ pCTX->v4l2_dec.mfc_dst_bufs[i][1] = mmap(NULL, buf.m.planes[1].length,
+ PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, buf.m.planes[1].m.mem_offset);
+ if (pCTX->v4l2_dec.mfc_dst_bufs[i][1] == MAP_FAILED) {
+ LOGE("[%s] mmap failed (destination buffers (UV))",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case2;
+ }
+#endif
+
+ ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ V4L2_MEMORY_MMAP, i, planes, 0);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case2;
+ }
+ }
+ pCTX->inter_buff_status |= MFC_USE_YUV_BUFF;
+
+ return 0;
+
+error_case2:
+ for (j = 0; j < i; j++) {
+ munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]);
+ munmap(pCTX->v4l2_dec.mfc_dst_bufs[j][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]);
+ }
+error_case1:
+ return ret;
+}
+
+int resolution_change(void *openHandle)
+{
+ int i, ret;
+ int req_count;
+ _MFCLIB *pCTX;
+ pCTX = (_MFCLIB *) openHandle;
+
+ ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret != 0)
+ goto error_case;
+
+ pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON);
+
+ for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; i++) {
+ munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][0], pCTX->v4l2_dec.mfc_dst_bufs_len[0]);
+ munmap(pCTX->v4l2_dec.mfc_dst_bufs[i][1], pCTX->v4l2_dec.mfc_dst_bufs_len[1]);
+ }
+ pCTX->inter_buff_status &= ~(MFC_USE_YUV_BUFF);
+
+ req_count = 0;
+ ret = v4l2_mfc_reqbufs(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ V4L2_MEMORY_MMAP, &req_count);
+ if (ret != 0)
+ goto error_case;
+
+ read_header_data(pCTX);
+ init_mfc_output_stream(pCTX);
+
+ ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret != 0)
+ goto error_case;
+ pCTX->inter_buff_status |= MFC_USE_DST_STREAMON;
+
+ return 0;
+
+error_case:
+ return ret;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill)
+{
+ _MFCLIB *pCTX;
+ int ret;
+
+ struct v4l2_buffer buf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+ int loop_count, ctrl_value;
+
+ int poll_state;
+ int poll_revents;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) {
+ LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)) {
+ if (pCTX->displayStatus != MFC_GETOUTBUF_DISPLAY_ONLY) {
+ /* Queue the stream frame */
+ ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, lengthBufFill);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__);
+ return MFC_RET_DEC_EXE_ERR;
+ }
+
+ memset(&buf, 0, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.m.planes = planes;
+ buf.length = 1;
+
+ /* wait for decoding */
+ do {
+ poll_state = v4l2_mfc_poll(pCTX->hMFC, &poll_revents, POLL_DEC_WAIT_TIMEOUT);
+ if (poll_state > 0) {
+ if (poll_revents & POLLOUT) {
+ ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP);
+ if (ret == 0) {
+ if (buf.flags & V4L2_BUF_FLAG_ERROR)
+ return MFC_RET_DEC_EXE_ERR;
+ pCTX->v4l2_dec.mfc_src_buf_flags[buf.index] = BUF_DEQUEUED;
+ break;
+ }
+ } else if (poll_revents & POLLERR) {
+ LOGE("[%s] POLLERR\n",__func__);
+ return MFC_RET_DEC_EXE_ERR;
+ } else {
+ LOGE("[%s] poll() returns 0x%x\n", __func__, poll_revents);
+ return MFC_RET_DEC_EXE_ERR;
+ }
+ } else if (poll_state < 0) {
+ return MFC_RET_DEC_EXE_ERR;
+ }
+
+ if (isBreak_loop(pCTX))
+ break;
+
+ } while(0 == poll_state);
+ }
+
+ ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP);
+ if (ret != 0) {
+ pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY;
+ pCTX->decOutInfo.disp_pic_frame_type = -1;
+ return MFC_RET_OK;
+ } else {
+ ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed", __func__);
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+
+ switch (ctrl_value) {
+ case 0:
+ pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY;
+ break;
+ case 1:
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING;
+ break;
+ case 2:
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY;
+ break;
+ case 3:
+ pCTX->displayStatus = MFC_GETOUTBUF_CHANGE_RESOL;
+ break;
+ }
+ }
+
+ if (pCTX->displayStatus == MFC_GETOUTBUF_CHANGE_RESOL) {
+ resolution_change(pCTX);
+ } else {
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1];
+ }
+
+ if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe)
+ pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED;
+
+ } else if (pCTX->v4l2_dec.bBeingFinalized == 0) {
+ pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED;
+ pCTX->v4l2_dec.bBeingFinalized = 1; /* true */
+
+ /* Queue the stream frame */
+ ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, 0);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__);
+ return MFC_RET_DEC_EXE_ERR;
+ }
+
+ /* wait for decoding */
+ loop_count = 0;
+ do {
+ ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP);
+ if (ret != 0)
+ usleep(1000);
+ loop_count++;
+ if (loop_count >= 1000) {
+ LOGE("[%s] Error in do-while loop",__func__);
+ break;
+ }
+ } while (ret != 0);
+
+ ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed", __func__);
+ return MFC_RET_DEC_EXE_ERR;
+ }
+ if (ctrl_value == 3) {
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END;
+ pCTX->decOutInfo.disp_pic_frame_type = -1;
+ return MFC_RET_OK;
+ }
+
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY;
+
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1];
+ } else {
+ loop_count = 0;
+ do {
+ ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP);
+ if (ret != 0)
+ usleep(1000);
+ loop_count++;
+ if (loop_count >= 1000) {
+ LOGE("[%s] Error in do-while loop",__func__);
+ break;
+ }
+ } while (ret != 0);
+
+ if (buf.m.planes[0].bytesused == 0) {
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END;
+ pCTX->decOutInfo.disp_pic_frame_type = -1;
+ return MFC_RET_OK;
+ } else {
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY;
+ }
+
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1];
+ }
+
+ pCTX->decOutInfo.disp_pic_frame_type = (buf.flags & (0x7 << 3));
+
+ switch (pCTX->decOutInfo.disp_pic_frame_type) {
+ case V4L2_BUF_FLAG_KEYFRAME:
+ pCTX->decOutInfo.disp_pic_frame_type = 1;
+ break;
+ case V4L2_BUF_FLAG_PFRAME:
+ pCTX->decOutInfo.disp_pic_frame_type = 2;
+ break;
+ case V4L2_BUF_FLAG_BFRAME:
+ pCTX->decOutInfo.disp_pic_frame_type = 3;
+ break;
+ default:
+ pCTX->decOutInfo.disp_pic_frame_type = 0;
+ break;
+ }
+
+ ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP,
+ buf.index, planes, 0);
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill)
+{
+ _MFCLIB *pCTX;
+ int ret;
+
+ struct v4l2_buffer buf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) {
+ LOGE("[%s] lengthBufFill is invalid. (lengthBufFill=%d)",__func__, lengthBufFill);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)
+ && (pCTX->displayStatus != MFC_GETOUTBUF_DISPLAY_ONLY)) {
+ /* Queue the stream frame */
+ ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, lengthBufFill);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__);
+ return MFC_RET_DEC_EXE_ERR;
+ }
+ } else if (pCTX->v4l2_dec.bBeingFinalized == 0) {
+ /* Queue the stream frame */
+ ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ V4L2_MEMORY_MMAP, pCTX->v4l2_dec.beingUsedIndex, planes, 0);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__);
+ return MFC_RET_DEC_EXE_ERR;
+ }
+ }
+
+ if ((SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) && (lengthBufFill == 0))
+ pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED;
+
+ return MFC_RET_OK;
+}
+
+int isBreak_loop(void *openHandle)
+{
+ _MFCLIB *pCTX;
+ pCTX = (_MFCLIB *) openHandle;
+ int ctrl_value;
+ int ret = 0;
+
+ if (pCTX->displayStatus == MFC_GETOUTBUF_DISPLAY_ONLY)
+ return 1;
+
+ ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_CHECK_STATE, &ctrl_value);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed", __func__);
+ return 0;
+ }
+
+ if (ctrl_value == MFCSTATE_DEC_RES_DETECT) {
+ LOGV("[%s] Resolution Change detect",__func__);
+ return 1;
+ } else if (ctrl_value == MFCSTATE_DEC_TERMINATING) {
+ LOGV("[%s] Decoding Finish!!!",__func__);
+ return 1;
+ }
+
+ return 0;
+}
+
+SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info)
+{
+ _MFCLIB *pCTX;
+ int ret;
+
+ struct v4l2_buffer buf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+ int loop_count, ctrl_value;
+
+ int poll_state;
+ int poll_revents;
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) {
+ if (pCTX->displayStatus != MFC_GETOUTBUF_DISPLAY_ONLY) {
+ /* wait for decoding */
+ do {
+ poll_state = v4l2_mfc_poll(pCTX->hMFC, &poll_revents, POLL_DEC_WAIT_TIMEOUT);
+ if (poll_state > 0) {
+ if (poll_revents & POLLOUT) {
+ buf.m.planes = planes;
+ buf.length = 1;
+ ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP);
+ if (ret == 0) {
+ if (buf.flags & V4L2_BUF_FLAG_ERROR)
+ return MFC_GETOUTBUF_STATUS_NULL;
+ pCTX->v4l2_dec.mfc_src_buf_flags[buf.index] = BUF_DEQUEUED;
+ break;
+ }
+ } else if (poll_revents & POLLERR) {
+ LOGE("[%s] POLLERR\n",__func__);
+ return MFC_GETOUTBUF_STATUS_NULL;
+ } else {
+ LOGE("[%s] poll() returns 0x%x\n", __func__, poll_revents);
+ return MFC_GETOUTBUF_STATUS_NULL;
+ }
+ } else if (poll_state < 0) {
+ return MFC_GETOUTBUF_STATUS_NULL;
+ }
+
+ if (isBreak_loop(pCTX))
+ break;
+
+ } while (0 == poll_state);
+ }
+
+ ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP);
+ if (ret != 0) {
+ pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY;
+ pCTX->decOutInfo.disp_pic_frame_type = -1;
+ return SsbSipMfcDecGetOutBuf(pCTX, output_info);;
+ } else {
+ ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed", __func__);
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+
+ switch (ctrl_value) {
+ case 0:
+ pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY;
+ break;
+ case 1:
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING;
+ break;
+ case 2:
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY;
+ break;
+ case 3:
+ pCTX->displayStatus = MFC_GETOUTBUF_CHANGE_RESOL;
+ break;
+ }
+ }
+
+ if (pCTX->displayStatus == MFC_GETOUTBUF_CHANGE_RESOL) {
+ resolution_change(pCTX);
+ } else {
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1];
+ }
+
+ if (SSBSIP_MFC_LAST_FRAME_RECEIVED == pCTX->lastframe)
+ pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED;
+ } else if (pCTX->v4l2_dec.bBeingFinalized == 0) {
+ pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_PROCESSED;
+ pCTX->v4l2_dec.bBeingFinalized = 1; /* true */
+
+ /* wait for decoding */
+ loop_count = 0;
+ do {
+ ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP);
+ if (ret != 0)
+ usleep(1000);
+ loop_count++;
+ if (loop_count >= 1000) {
+ LOGE("[%s] Error in do-while loop",__func__);
+ break;
+ }
+ } while (ret != 0);
+
+ ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_DISPLAY_STATUS, &ctrl_value);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed", __func__);
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+ if (ctrl_value == 3) {
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END;
+ pCTX->decOutInfo.disp_pic_frame_type = -1;
+ return SsbSipMfcDecGetOutBuf(pCTX, output_info);;
+ }
+
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY;
+
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1];
+ } else {
+ loop_count = 0;
+ do {
+ ret = v4l2_mfc_dqbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP);
+ if (ret != 0)
+ usleep(1000);
+ loop_count++;
+ if (loop_count >= 1000) {
+ LOGE("[%s] Error in do-while loop",__func__);
+ break;
+ }
+ } while (ret != 0);
+
+ if (buf.m.planes[0].bytesused == 0) {
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_END;
+ pCTX->decOutInfo.disp_pic_frame_type = -1;
+ return SsbSipMfcDecGetOutBuf(pCTX, output_info);;
+ } else {
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY;
+ }
+
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[buf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[buf.index][1];
+ }
+
+ pCTX->decOutInfo.disp_pic_frame_type = (buf.flags & (0x7 << 3));
+
+ switch (pCTX->decOutInfo.disp_pic_frame_type) {
+ case V4L2_BUF_FLAG_KEYFRAME:
+ pCTX->decOutInfo.disp_pic_frame_type = 1;
+ break;
+ case V4L2_BUF_FLAG_PFRAME:
+ pCTX->decOutInfo.disp_pic_frame_type = 2;
+ break;
+ case V4L2_BUF_FLAG_BFRAME:
+ pCTX->decOutInfo.disp_pic_frame_type = 3;
+ break;
+ default:
+ pCTX->decOutInfo.disp_pic_frame_type = 0;
+ break;
+ }
+
+ ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_MEMORY_MMAP,
+ buf.index, planes, 0);
+
+ return SsbSipMfcDecGetOutBuf(pCTX, output_info);
+}
+
+void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize)
+{
+ _MFCLIB *pCTX;
+ int i;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return NULL;
+ }
+
+ if ((inputBufferSize < 0) || (inputBufferSize > MAX_DECODER_INPUT_BUFFER_SIZE)) {
+ LOGE("[%s] inputBufferSize = %d is invalid",__func__, inputBufferSize);
+ return NULL;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ for (i = 0; i < MFC_DEC_NUM_SRC_BUFS; i++)
+ if (BUF_DEQUEUED == pCTX->v4l2_dec.mfc_src_buf_flags[i])
+ break;
+
+ if (i == MFC_DEC_NUM_SRC_BUFS) {
+ LOGV("[%s] No buffer is available.",__func__);
+ return NULL;
+ } else {
+ pCTX->virStrmBuf = (unsigned int)pCTX->v4l2_dec.mfc_src_bufs[i];
+ pCTX->v4l2_dec.beingUsedIndex = i;
+ /* Set the buffer flag as Enqueued for NB_mode_process*/
+ /* FIXME: Check this assignment in case of using New API ExeNb() */
+ pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED;
+ }
+
+ return (void *)pCTX->virStrmBuf;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size)
+{
+ _MFCLIB *pCTX;
+ int i;
+
+ LOGV("[%s] Enter",__func__);
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ for (i = 0; i < MFC_DEC_NUM_SRC_BUFS; i++) {
+ if (pCTX->v4l2_dec.mfc_src_bufs[i] == virInBuf)
+ break;
+ }
+
+ if (i == MFC_DEC_NUM_SRC_BUFS) {
+ LOGE("[%s] Can not use the buffer",__func__);
+ return MFC_RET_INVALID_PARAM;
+ } else {
+ pCTX->virStrmBuf = (unsigned int)virInBuf;
+ pCTX->v4l2_dec.beingUsedIndex = i;
+ pCTX->v4l2_dec.mfc_src_buf_flags[i] = BUF_ENQUEUED;
+ }
+ LOGV("[%s] Exit idx %d",__func__,pCTX->v4l2_dec.beingUsedIndex);
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info)
+{
+ _MFCLIB *pCTX;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_GETOUTBUF_DISPLAY_END;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr;
+ output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr;
+
+ output_info->YVirAddr = pCTX->decOutInfo.YVirAddr;
+ output_info->CVirAddr = pCTX->decOutInfo.CVirAddr;
+
+ output_info->img_width = pCTX->decOutInfo.img_width;
+ output_info->img_height= pCTX->decOutInfo.img_height;
+
+ output_info->buf_width = pCTX->decOutInfo.buf_width;
+ output_info->buf_height= pCTX->decOutInfo.buf_height;
+
+ output_info->crop_right_offset = pCTX->decOutInfo.crop_right_offset;
+ output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset;
+ output_info->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset;
+ output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset;
+
+ output_info->disp_pic_frame_type = pCTX->decOutInfo.disp_pic_frame_type;
+
+ switch (pCTX->displayStatus) {
+ case MFC_GETOUTBUF_DISPLAY_ONLY:
+ case MFC_GETOUTBUF_DISPLAY_DECODING:
+ case MFC_GETOUTBUF_DISPLAY_END:
+ case MFC_GETOUTBUF_DECODING_ONLY:
+ case MFC_GETOUTBUF_CHANGE_RESOL:
+ break;
+ default:
+ return MFC_GETOUTBUF_DISPLAY_END;
+ }
+
+ return pCTX->displayStatus;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value)
+{
+ int ret, i;
+
+ _MFCLIB *pCTX;
+ struct mfc_dec_fimv1_info *fimv1_res;
+
+ struct v4l2_buffer buf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+
+ int id, ctrl_value;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if ((value == NULL) && (MFC_DEC_SETCONF_IS_LAST_FRAME !=conf_type)) {
+ LOGE("[%s] value is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ /* First, process non-ioctl calling settings */
+ switch (conf_type) {
+ case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM:
+ pCTX->dec_numextradpb = *((unsigned int *) value);
+ return MFC_RET_OK;
+
+ case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT: /* be set before calling SsbSipMfcDecInit */
+ fimv1_res = (struct mfc_dec_fimv1_info *)value;
+ LOGI("fimv1->width = %d\n", fimv1_res->width);
+ LOGI("fimv1->height = %d\n", fimv1_res->height);
+ pCTX->fimv1_res.width = (int)(fimv1_res->width);
+ pCTX->fimv1_res.height = (int)(fimv1_res->height);
+ return MFC_RET_OK;
+
+ case MFC_DEC_SETCONF_IS_LAST_FRAME:
+ if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) {
+ pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED;
+ return MFC_RET_OK;
+ } else {
+ return MFC_RET_FAIL;
+ }
+
+ case MFC_DEC_SETCONF_DPB_FLUSH:
+ ret = v4l2_mfc_streamoff(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__);
+ return MFC_RET_DEC_SET_CONF_FAIL;
+ }
+ pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON);
+
+ for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) {
+ ret = v4l2_mfc_qbuf(pCTX->hMFC, &buf, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ V4L2_MEMORY_MMAP, i, planes, 0);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__);
+ return MFC_RET_DEC_SET_CONF_FAIL;
+ }
+ }
+
+ ret = v4l2_mfc_streamon(pCTX->hMFC, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_STREAMON failed (destination buffers)",__func__);
+ return MFC_RET_DEC_SET_CONF_FAIL;
+ }
+ pCTX->inter_buff_status |= MFC_USE_DST_STREAMON;
+ return MFC_RET_OK;
+ default:
+ /* Others will be processed next */
+ break;
+ }
+
+ /* Process ioctl calling settings */
+ switch (conf_type) {
+ case MFC_DEC_SETCONF_DISPLAY_DELAY: /* be set before calling SsbSipMfcDecInit */
+ id = V4L2_CID_CODEC_DISPLAY_DELAY;
+ ctrl_value = *((unsigned int *) value);
+ break;
+
+ case MFC_DEC_SETCONF_CRC_ENABLE:
+ id = V4L2_CID_CODEC_CRC_ENABLE;
+ ctrl_value = 1;
+ break;
+
+ case MFC_DEC_SETCONF_SLICE_ENABLE:
+ id = V4L2_CID_CODEC_SLICE_INTERFACE;
+ ctrl_value = 1;
+ break;
+
+ case MFC_DEC_SETCONF_FRAME_TAG: /*be set before calling SsbSipMfcDecExe */
+ id = V4L2_CID_CODEC_FRAME_TAG;
+ ctrl_value = *((unsigned int*)value);
+ break;
+
+ case MFC_DEC_SETCONF_POST_ENABLE:
+ id = V4L2_CID_CODEC_LOOP_FILTER_MPEG4_ENABLE;
+ ctrl_value = *((unsigned int*)value);
+ break;
+#ifdef S3D_SUPPORT
+ case MFC_DEC_SETCONF_SEI_PARSE:
+ id = V4L2_CID_CODEC_FRAME_PACK_SEI_PARSE;
+ ctrl_value = 1;
+ break;
+#endif
+ default:
+ LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ ret = v4l2_mfc_s_ctrl(pCTX->hMFC, id, ctrl_value);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_S_CTRL failed (conf_type = %d)",__func__, conf_type);
+ return MFC_RET_DEC_SET_CONF_FAIL;
+ }
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value)
+{
+ _MFCLIB *pCTX;
+
+ SSBSIP_MFC_IMG_RESOLUTION *img_resolution;
+ int ret;
+ SSBSIP_MFC_CRC_DATA *crc_data;
+#ifdef S3D_SUPPORT
+ SSBSIP_MFC_FRAME_PACKING *frame_packing;
+ struct mfc_frame_pack_sei_info sei_info;
+#endif
+ SSBSIP_MFC_CROP_INFORMATION *crop_information;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if (value == NULL) {
+ LOGE("[%s] value is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ switch (conf_type) {
+ case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT:
+ img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value;
+ img_resolution->width = pCTX->decOutInfo.img_width;
+ img_resolution->height = pCTX->decOutInfo.img_height;
+ img_resolution->buf_width = pCTX->decOutInfo.buf_width;
+ img_resolution->buf_height = pCTX->decOutInfo.buf_height;
+ break;
+
+ case MFC_DEC_GETCONF_FRAME_TAG:
+ ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_FRAME_TAG, (int*)value);
+ if (ret != 0)
+ LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_FRAME_TAG", __func__);
+ break;
+
+ case MFC_DEC_GETCONF_CRC_DATA:
+ crc_data = (SSBSIP_MFC_CRC_DATA *) value;
+
+ ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_CRC_DATA_LUMA, &crc_data->luma0);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_LUMA",__func__);
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+
+ ret = v4l2_mfc_g_ctrl(pCTX->hMFC, V4L2_CID_CODEC_CRC_DATA_CHROMA, &crc_data->chroma0);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_CHROMA",__func__);
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+ LOGI("[%s] crc_data->luma0=0x%x\n", __func__, crc_data->luma0);
+ LOGI("[%s] crc_data->chroma0=0x%x\n", __func__, crc_data->chroma0);
+ break;
+#ifdef S3D_SUPPORT
+ case MFC_DEC_GETCONF_FRAME_PACKING:
+ frame_packing = (SSBSIP_MFC_FRAME_PACKING *)value;
+
+ ret = v4l2_mfc_ext_g_ctrl(pCTX->hMFC, conf_type, &sei_info);
+ if (ret != 0) {
+ printf("Error to do ext_g_ctrl.\n");
+ }
+ frame_packing->available = sei_info.sei_avail;
+ frame_packing->arrangement_id = sei_info.arrgment_id;
+
+ frame_packing->arrangement_cancel_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 0);
+ frame_packing->arrangement_type = OPERATE_BIT(sei_info.sei_info, 0x3f, 1);
+ frame_packing->quincunx_sampling_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 8);
+ frame_packing->content_interpretation_type = OPERATE_BIT(sei_info.sei_info, 0x3f, 9);
+ frame_packing->spatial_flipping_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 15);
+ frame_packing->frame0_flipped_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 16);
+ frame_packing->field_views_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 17);
+ frame_packing->current_frame_is_frame0_flag = OPERATE_BIT(sei_info.sei_info, 0x1, 18);
+
+ frame_packing->frame0_grid_pos_x = OPERATE_BIT(sei_info.sei_info, 0xf, 0);
+ frame_packing->frame0_grid_pos_y = OPERATE_BIT(sei_info.sei_info, 0xf, 4);
+ frame_packing->frame1_grid_pos_x = OPERATE_BIT(sei_info.sei_info, 0xf, 8);
+ frame_packing->frame1_grid_pos_y = OPERATE_BIT(sei_info.sei_info, 0xf, 12);
+ break;
+#endif
+ case MFC_DEC_GETCONF_CROP_INFO:
+ crop_information = (SSBSIP_MFC_CROP_INFORMATION *)value;
+ crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset;
+ crop_information->crop_bottom_offset = pCTX->decOutInfo.crop_bottom_offset;
+ crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset;
+ crop_information->crop_right_offset = pCTX->decOutInfo.crop_right_offset;
+ break;
+
+ default:
+ LOGE("[%s] conf_type(%d) is NOT supported",__func__, conf_type);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ return MFC_RET_OK;
+}
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c
new file mode 100644
index 0000000..2333b6c
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c
@@ -0,0 +1,1506 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <sys/poll.h>
+#include "videodev2.h"
+
+#include "mfc_interface.h"
+#include "SsbSipMfcApi.h"
+
+/* #define LOG_NDEBUG 0 */
+#define LOG_TAG "MFC_ENC_APP"
+#include <utils/Log.h>
+
+#define POLL_ENC_WAIT_TIMEOUT 25
+
+#ifndef true
+#define true (1)
+#endif
+
+#ifndef false
+#define false (0)
+#endif
+
+#define MAX_STREAM_SIZE (2*1024*1024)
+
+static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME;
+static int mfc_dev_node = 7;
+
+#if defined (MFC5x_VERSION)
+#define H263_CTRL_NUM 19
+#define MPEG4_CTRL_NUM 27
+#define H264_CTRL_NUM 50
+#elif defined (MFC6x_VERSION)
+#define H263_CTRL_NUM 20
+#define MPEG4_CTRL_NUM 28
+#define H264_CTRL_NUM 67
+#endif
+
+
+static void getMFCName(char *devicename, int size)
+{
+ snprintf(devicename, size, "%s%d", SAMSUNG_MFC_DEV_NAME, mfc_dev_node);
+}
+
+void SsbSipMfcEncSetMFCName(char *devicename)
+{
+ mfc_dev_name = devicename;
+}
+
+void *SsbSipMfcEncOpen(void)
+{
+ int hMFCOpen;
+ _MFCLIB *pCTX;
+
+ char mfc_dev_name[64];
+
+ int ret;
+ struct v4l2_capability cap;
+
+ LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR);
+ getMFCName(mfc_dev_name, 64);
+ LOGI("[%s] dev name is %s\n",__func__,mfc_dev_name);
+
+ if (access(mfc_dev_name, F_OK) != 0) {
+ LOGE("[%s] MFC device node not exists",__func__);
+ return NULL;
+ }
+
+ hMFCOpen = open(mfc_dev_name, O_RDWR | O_NONBLOCK, 0);
+ if (hMFCOpen < 0) {
+ LOGE("[%s] Failed to open MFC device",__func__);
+ return NULL;
+ }
+
+ pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
+ if (pCTX == NULL) {
+ LOGE("[%s] malloc failed.",__func__);
+ return NULL;
+ }
+ memset(pCTX, 0, sizeof(_MFCLIB));
+
+ pCTX->hMFC = hMFCOpen;
+
+ memset(&cap, 0, sizeof(cap));
+ ret = ioctl(pCTX->hMFC, VIDIOC_QUERYCAP, &cap);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QUERYCAP failed",__func__);
+ close(pCTX->hMFC);
+ free(pCTX);
+ return NULL;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
+ LOGE("[%s] Device does not support capture",__func__);
+ close(pCTX->hMFC);
+ free(pCTX);
+ return NULL;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
+ LOGE("[%s] Device does not support output",__func__);
+ close(pCTX->hMFC);
+ free(pCTX);
+ return NULL;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
+ LOGE("[%s] Device does not support streaming",__func__);
+ close(pCTX->hMFC);
+ free(pCTX);
+ return NULL;
+ }
+
+ pCTX->v4l2_enc.bRunning = 0;
+ /* physical address is used for Input source */
+ pCTX->v4l2_enc.bInputPhyVir = 1;
+
+ pCTX->cacheablebuffer = NO_CACHE;
+
+ return (void *)pCTX;
+}
+
+void *SsbSipMfcEncOpenExt(void *value)
+{
+ _MFCLIB *pCTX;
+
+ pCTX = SsbSipMfcEncOpen();
+ if (pCTX == NULL)
+ return NULL;
+
+ if (NO_CACHE == (*(SSBIP_MFC_BUFFER_TYPE *)value)) {
+ pCTX->cacheablebuffer = NO_CACHE;
+ /* physical address is used for Input source */
+ pCTX->v4l2_enc.bInputPhyVir = 1;
+ LOGI("[%s] non cacheable buffer",__func__);
+ }
+ else {
+ pCTX->cacheablebuffer = CACHE;
+ /* vitual address is used for Input source */
+ pCTX->v4l2_enc.bInputPhyVir = 0;
+ LOGI("[%s] cacheable buffer",__func__);
+ }
+
+ return (void *)pCTX;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle)
+{
+ _MFCLIB *pCTX;
+ int ret, i;
+
+ enum v4l2_buf_type type;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ if (pCTX->inter_buff_status & MFC_USE_DST_STREAMON) {
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_STREAMOFF failed (destination buffers)",__func__);
+ return MFC_RET_CLOSE_FAIL;
+ }
+ pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON);
+ }
+
+ if (pCTX->inter_buff_status & MFC_USE_SRC_STREAMON) {
+ type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ ret = ioctl(pCTX->hMFC, VIDIOC_STREAMOFF, &type);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_STREAMOFF failed (source buffers)",__func__);
+ return MFC_RET_CLOSE_FAIL;
+ }
+ pCTX->inter_buff_status &= ~(MFC_USE_SRC_STREAMON);
+ }
+
+ if (!pCTX->v4l2_enc.bInputPhyVir) {
+ for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++) {
+ munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]);
+ munmap(pCTX->v4l2_enc.mfc_src_bufs[i][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]);
+ }
+ }
+
+ for (i = 0; i < pCTX->v4l2_enc.mfc_num_dst_bufs; i++)
+ munmap(pCTX->v4l2_enc.mfc_dst_bufs[i], pCTX->v4l2_enc.mfc_dst_bufs_len);
+
+ pCTX->inter_buff_status = MFC_USE_NONE;
+
+ close(pCTX->hMFC);
+
+ free(pCTX);
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param)
+{
+ int ret, i, j,index;
+ _MFCLIB *pCTX;
+
+ enum v4l2_buf_type type;
+ struct v4l2_format fmt;
+ struct v4l2_plane planes[MFC_ENC_NUM_PLANES];
+
+ struct v4l2_buffer buf;
+ struct v4l2_requestbuffers reqbuf;
+
+ struct v4l2_control ctrl;
+
+ struct pollfd poll_events;
+ int poll_state;
+
+ struct v4l2_ext_control ext_ctrl_mpeg4[MPEG4_CTRL_NUM];
+ struct v4l2_ext_control ext_ctrl_h263[H263_CTRL_NUM];
+ struct v4l2_ext_control ext_ctrl[H264_CTRL_NUM];
+ struct v4l2_ext_controls ext_ctrls;
+
+ SSBSIP_MFC_ENC_H264_PARAM *h264_arg;
+ SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg;
+ SSBSIP_MFC_ENC_H263_PARAM *h263_arg;
+
+ if (openHandle == NULL)
+ return MFC_RET_INVALID_PARAM;
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param;
+ if (mpeg4_arg->codecType == MPEG4_ENC) {
+ pCTX->codecType= MPEG4_ENC;
+ pCTX->width = mpeg4_arg->SourceWidth;
+ pCTX->height = mpeg4_arg->SourceHeight;
+ pCTX->framemap = mpeg4_arg->FrameMap;
+ } else {
+ h263_arg = (SSBSIP_MFC_ENC_H263_PARAM*)param;
+ if (h263_arg->codecType == H263_ENC) {
+ pCTX->codecType = H263_ENC;
+ pCTX->width = h263_arg->SourceWidth;
+ pCTX->height = h263_arg->SourceHeight;
+ pCTX->framemap = h263_arg->FrameMap;
+ } else {
+ h264_arg = (SSBSIP_MFC_ENC_H264_PARAM*)param;
+ if (h264_arg->codecType == H264_ENC) {
+ pCTX->codecType = H264_ENC;
+ pCTX->width = h264_arg->SourceWidth;
+ pCTX->height = h264_arg->SourceHeight;
+ pCTX->framemap = h264_arg->FrameMap;
+ } else {
+ LOGE("[%s] Undefined codec type \n",__func__);
+ ret = MFC_RET_INVALID_PARAM;
+ goto error_case1;
+ }
+ }
+ }
+
+ switch (pCTX->codecType) {
+ case MPEG4_ENC:
+ ext_ctrl_mpeg4[0].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_PROFILE;
+ ext_ctrl_mpeg4[0].value = mpeg4_arg->ProfileIDC;
+ ext_ctrl_mpeg4[1].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_LEVEL;
+ ext_ctrl_mpeg4[1].value = mpeg4_arg->LevelIDC;
+ ext_ctrl_mpeg4[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE;
+ ext_ctrl_mpeg4[2].value = mpeg4_arg->IDRPeriod;
+ ext_ctrl_mpeg4[3].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_QUARTER_PIXEL;
+ ext_ctrl_mpeg4[3].value = mpeg4_arg->DisableQpelME;
+
+ ext_ctrl_mpeg4[4].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE;
+ ext_ctrl_mpeg4[4].value = mpeg4_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */
+ if (mpeg4_arg->SliceMode == 0) {
+ ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB;
+ ext_ctrl_mpeg4[5].value = 1; /* default */
+#if defined (MFC5x_VERSION)
+ ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl_mpeg4[6].value = 1900; /* default */
+#elif defined (MFC6x_VERSION)
+ ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl_mpeg4[6].value = 2800; /* based on MFC6.x */
+#endif
+ } else if (mpeg4_arg->SliceMode == 1) {
+ ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB;
+ ext_ctrl_mpeg4[5].value = mpeg4_arg->SliceArgument;
+#if defined (MFC5x_VERSION)
+ ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl_mpeg4[6].value = 1900; /* default */
+#elif defined (MFC6x_VERSION)
+ ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl_mpeg4[6].value = 2800; /* based on MFC6.x */
+#endif
+ } else if (mpeg4_arg->SliceMode == 3) {
+ ext_ctrl_mpeg4[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB;
+ ext_ctrl_mpeg4[5].value = 1; /* default */
+ ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl_mpeg4[6].value = mpeg4_arg->SliceArgument;
+ }
+ /*
+ * It should be set using mpeg4_arg->NumberBFrames after being handled by appl.
+ */
+ ext_ctrl_mpeg4[7].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_B_FRAMES;
+ ext_ctrl_mpeg4[7].value = mpeg4_arg->NumberBFrames;
+ ext_ctrl_mpeg4[8].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB;
+ ext_ctrl_mpeg4[8].value = mpeg4_arg->RandomIntraMBRefresh;
+
+ ext_ctrl_mpeg4[9].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE;
+ ext_ctrl_mpeg4[9].value = mpeg4_arg->PadControlOn;
+ ext_ctrl_mpeg4[10].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE;
+ ext_ctrl_mpeg4[10].value = mpeg4_arg->LumaPadVal;
+ ext_ctrl_mpeg4[11].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE;
+ ext_ctrl_mpeg4[11].value = mpeg4_arg->CbPadVal;
+ ext_ctrl_mpeg4[12].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE;
+ ext_ctrl_mpeg4[12].value = mpeg4_arg->CrPadVal;
+
+ ext_ctrl_mpeg4[13].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE;
+ ext_ctrl_mpeg4[13].value = mpeg4_arg->EnableFRMRateControl;
+ ext_ctrl_mpeg4[14].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_TIME_RES;
+ ext_ctrl_mpeg4[14].value = mpeg4_arg->TimeIncreamentRes;
+ ext_ctrl_mpeg4[15].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_VOP_FRM_DELTA;
+ ext_ctrl_mpeg4[15].value = mpeg4_arg->VopTimeIncreament;
+ ext_ctrl_mpeg4[16].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE;
+ ext_ctrl_mpeg4[16].value = mpeg4_arg->Bitrate;
+
+ ext_ctrl_mpeg4[17].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_FRAME_QP;
+ ext_ctrl_mpeg4[17].value = mpeg4_arg->FrameQp;
+ ext_ctrl_mpeg4[18].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_P_FRAME_QP;
+ ext_ctrl_mpeg4[18].value = mpeg4_arg->FrameQp_P;
+ ext_ctrl_mpeg4[19].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_B_FRAME_QP;
+ ext_ctrl_mpeg4[19].value = mpeg4_arg->FrameQp_B;
+
+ ext_ctrl_mpeg4[20].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MAX_QP;
+ ext_ctrl_mpeg4[20].value = mpeg4_arg->QSCodeMax;
+ ext_ctrl_mpeg4[21].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MIN_QP;
+ ext_ctrl_mpeg4[21].value = mpeg4_arg->QSCodeMin;
+ ext_ctrl_mpeg4[22].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF;
+ ext_ctrl_mpeg4[22].value = mpeg4_arg->CBRPeriodRf;
+
+ if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) {
+ ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE;
+ ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL;
+ } else if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) {
+ ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE;
+ ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE;
+ } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */
+ ext_ctrl_mpeg4[23].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE;
+ ext_ctrl_mpeg4[23].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE;
+ }
+
+ ext_ctrl_mpeg4[24].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE;
+ ext_ctrl_mpeg4[24].value = 0;
+
+ ext_ctrl_mpeg4[25].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE;
+ ext_ctrl_mpeg4[25].value = 0;
+
+ ext_ctrl_mpeg4[26].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT;
+ ext_ctrl_mpeg4[26].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE;
+
+#if defined (MFC6x_VERSION)
+ ext_ctrl_mpeg4[27].id = V4L2_CID_CODEC_MFC5X_ENC_MPEG4_RC_MB_ENABLE; /* MFC 6.x Only */
+ ext_ctrl_mpeg4[27].value = mpeg4_arg->EnableMBRateControl;
+#endif
+ break;
+
+ case H263_ENC:
+ ext_ctrl_h263[0].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE;
+ ext_ctrl_h263[0].value = h263_arg->IDRPeriod;
+
+ ext_ctrl_h263[1].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE;
+ ext_ctrl_h263[1].value = h263_arg->SliceMode; /* 0: one, Check is needed if h264 support multi-slice */
+
+ ext_ctrl_h263[2].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB;
+ ext_ctrl_h263[2].value = h263_arg->RandomIntraMBRefresh;
+
+ ext_ctrl_h263[3].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE;
+ ext_ctrl_h263[3].value = h263_arg->PadControlOn;
+ ext_ctrl_h263[4].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE;
+ ext_ctrl_h263[4].value = h263_arg->LumaPadVal;
+ ext_ctrl_h263[5].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE;
+ ext_ctrl_h263[5].value = h263_arg->CbPadVal;
+ ext_ctrl_h263[6].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE;
+ ext_ctrl_h263[6].value = h263_arg->CrPadVal;
+
+ ext_ctrl_h263[7].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE;
+ ext_ctrl_h263[7].value = h263_arg->EnableFRMRateControl;
+
+ ext_ctrl_h263[8].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_RATE;
+ ext_ctrl_h263[8].value = h263_arg->FrameRate;
+
+ ext_ctrl_h263[9].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE;
+ ext_ctrl_h263[9].value = h263_arg->Bitrate;
+
+ ext_ctrl_h263[10].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_FRAME_QP;
+ ext_ctrl_h263[10].value = h263_arg->FrameQp;
+ ext_ctrl_h263[11].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_P_FRAME_QP;
+ ext_ctrl_h263[11].value = h263_arg->FrameQp_P;
+
+ ext_ctrl_h263[12].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MAX_QP;
+ ext_ctrl_h263[12].value = h263_arg->QSCodeMax;
+ ext_ctrl_h263[13].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MIN_QP;
+ ext_ctrl_h263[13].value = h263_arg->QSCodeMin;
+ ext_ctrl_h263[14].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF;
+ ext_ctrl_h263[14].value = h263_arg->CBRPeriodRf;
+
+ if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) {
+ ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE;
+ ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL;
+ } else if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) {
+ ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE;
+ ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE;
+ } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */
+ ext_ctrl_h263[15].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE;
+ ext_ctrl_h263[15].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE;
+ }
+
+ ext_ctrl_h263[16].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE;
+ ext_ctrl_h263[16].value = 0;
+
+ ext_ctrl_h263[17].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE;
+ ext_ctrl_h263[17].value = 0;
+
+ ext_ctrl_h263[18].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT;
+ ext_ctrl_h263[18].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE;
+
+#if defined (MFC6x_VERSION)
+ ext_ctrl_h263[19].id = V4L2_CID_CODEC_MFC5X_ENC_H263_RC_MB_ENABLE; /* MFC 6.x Only */
+ ext_ctrl_h263[19].value = h263_arg->EnableMBRateControl;
+#endif
+ break;
+
+ case H264_ENC:
+ ext_ctrl[0].id = V4L2_CID_CODEC_MFC5X_ENC_H264_PROFILE;
+ ext_ctrl[0].value = h264_arg->ProfileIDC;
+ ext_ctrl[1].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LEVEL;
+ ext_ctrl[1].value = h264_arg->LevelIDC;
+ ext_ctrl[2].id = V4L2_CID_CODEC_MFC5X_ENC_GOP_SIZE;
+ ext_ctrl[2].value = h264_arg->IDRPeriod;
+ ext_ctrl[3].id = V4L2_CID_CODEC_MFC5X_ENC_H264_MAX_REF_PIC;
+ ext_ctrl[3].value = h264_arg->NumberReferenceFrames;
+ ext_ctrl[4].id = V4L2_CID_CODEC_MFC5X_ENC_H264_NUM_REF_PIC_4P;
+ ext_ctrl[4].value = h264_arg->NumberRefForPframes;
+ ext_ctrl[5].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MODE;
+ ext_ctrl[5].value = h264_arg->SliceMode; /* 0: one, 1: fixed #mb, 3: fixed #bytes */
+ if (h264_arg->SliceMode == 0) {
+ ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB;
+ ext_ctrl[6].value = 1; /* default */
+#if defined (MFC5x_VERSION)
+ ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl[7].value = 1900; /* default */
+#elif defined (MFC6x_VERSION)
+ ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl[7].value = 2800; /* based on MFC6.x */
+#endif
+ } else if (h264_arg->SliceMode == 1) {
+ ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB;
+ ext_ctrl[6].value = h264_arg->SliceArgument;
+#if defined (MFC5x_VERSION)
+ ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl[7].value = 1900; /* default */
+#elif defined (MFC6x_VERSION)
+ ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl[7].value = 2800; /* based on MFC6.x */
+#endif
+ } else if (h264_arg->SliceMode == 3) {
+ ext_ctrl[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_MB;
+ ext_ctrl[6].value = 1; /* default */
+ ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl[7].value = h264_arg->SliceArgument;
+ }
+ /*
+ * It should be set using h264_arg->NumberBFrames after being handled by appl.
+ */
+ ext_ctrl[8].id = V4L2_CID_CODEC_MFC5X_ENC_H264_B_FRAMES;
+ ext_ctrl[8].value = h264_arg->NumberBFrames;
+ ext_ctrl[9].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_MODE;
+ ext_ctrl[9].value = h264_arg->LoopFilterDisable;
+ ext_ctrl[10].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_ALPHA;
+ ext_ctrl[10].value = h264_arg->LoopFilterAlphaC0Offset;
+ ext_ctrl[11].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LOOP_FILTER_BETA;
+ ext_ctrl[11].value = h264_arg->LoopFilterBetaOffset;
+ ext_ctrl[12].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ENTROPY_MODE;
+ ext_ctrl[12].value = h264_arg->SymbolMode;
+ ext_ctrl[13].id = V4L2_CID_CODEC_MFC5X_ENC_H264_INTERLACE;
+ ext_ctrl[13].value = h264_arg->PictureInterlace;
+ ext_ctrl[14].id = V4L2_CID_CODEC_MFC5X_ENC_H264_8X8_TRANSFORM;
+ ext_ctrl[14].value = h264_arg->Transform8x8Mode;
+ ext_ctrl[15].id = V4L2_CID_CODEC_MFC5X_ENC_INTRA_REFRESH_MB;
+ ext_ctrl[15].value = h264_arg->RandomIntraMBRefresh;
+ ext_ctrl[16].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CTRL_ENABLE;
+ ext_ctrl[16].value = h264_arg->PadControlOn;
+ ext_ctrl[17].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_LUMA_VALUE;
+ ext_ctrl[17].value = h264_arg->LumaPadVal;
+ ext_ctrl[18].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CB_VALUE;
+ ext_ctrl[18].value = h264_arg->CbPadVal;
+ ext_ctrl[19].id = V4L2_CID_CODEC_MFC5X_ENC_PAD_CR_VALUE;
+ ext_ctrl[19].value = h264_arg->CrPadVal;
+ ext_ctrl[20].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FRAME_ENABLE;
+ ext_ctrl[20].value = h264_arg->EnableFRMRateControl;
+ ext_ctrl[21].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ENABLE;
+ ext_ctrl[21].value = h264_arg->EnableMBRateControl;
+ ext_ctrl[22].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_RATE;
+ ext_ctrl[22].value = h264_arg->FrameRate;
+ ext_ctrl[23].id = V4L2_CID_CODEC_MFC5X_ENC_RC_BIT_RATE;
+ /* FIXME temporary fix */
+ if (h264_arg->Bitrate)
+ ext_ctrl[23].value = h264_arg->Bitrate;
+ else
+ ext_ctrl[23].value = 1; /* just for testing Movi studio */
+ ext_ctrl[24].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_FRAME_QP;
+ ext_ctrl[24].value = h264_arg->FrameQp;
+ ext_ctrl[25].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_P_FRAME_QP;
+ ext_ctrl[25].value = h264_arg->FrameQp_P;
+ ext_ctrl[26].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_B_FRAME_QP;
+ ext_ctrl[26].value = h264_arg->FrameQp_B;
+ ext_ctrl[27].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MAX_QP;
+ ext_ctrl[27].value = h264_arg->QSCodeMax;
+ ext_ctrl[28].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MIN_QP;
+ ext_ctrl[28].value = h264_arg->QSCodeMin;
+ ext_ctrl[29].id = V4L2_CID_CODEC_MFC5X_ENC_RC_REACTION_COEFF;
+ ext_ctrl[29].value = h264_arg->CBRPeriodRf;
+ ext_ctrl[30].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_DARK;
+ ext_ctrl[30].value = h264_arg->DarkDisable;
+ ext_ctrl[31].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_SMOOTH;
+ ext_ctrl[31].value = h264_arg->SmoothDisable;
+ ext_ctrl[32].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_STATIC;
+ ext_ctrl[32].value = h264_arg->StaticDisable;
+ ext_ctrl[33].id = V4L2_CID_CODEC_MFC5X_ENC_H264_RC_MB_ACTIVITY;
+ ext_ctrl[33].value = h264_arg->ActivityDisable;
+
+ /* doesn't have to be set */
+ ext_ctrl[34].id = V4L2_CID_CODEC_MFC5X_ENC_H264_OPEN_GOP;
+ ext_ctrl[34].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE;
+ ext_ctrl[35].id = V4L2_CID_CODEC_MFC5X_ENC_H264_I_PERIOD;
+ ext_ctrl[35].value = 10;
+
+ if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL == pCTX->enc_frameskip) {
+ ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE;
+ ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_LEVEL;
+ } else if (V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE == pCTX->enc_frameskip) {
+ ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE;
+ ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_VBV_BUF_SIZE;
+ } else { /* ENC_FRAME_SKIP_MODE_DISABLE (default) */
+ ext_ctrl[36].id = V4L2_CID_CODEC_MFC5X_ENC_FRAME_SKIP_MODE;
+ ext_ctrl[36].value = V4L2_CODEC_MFC5X_ENC_FRAME_SKIP_MODE_DISABLE;
+ }
+
+ ext_ctrl[37].id = V4L2_CID_CODEC_MFC5X_ENC_VBV_BUF_SIZE;
+ ext_ctrl[37].value = 0;
+
+ ext_ctrl[38].id = V4L2_CID_CODEC_MFC5X_ENC_SEQ_HDR_MODE;
+ ext_ctrl[38].value = 0; /* 0: seperated header, 1: header + first frame */
+
+ ext_ctrl[39].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_ENABLE;
+ ext_ctrl[39].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE;
+ ext_ctrl[40].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_IDC;
+ ext_ctrl[40].value = 0;
+ ext_ctrl[41].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_WIDTH;
+ ext_ctrl[41].value = 0;
+ ext_ctrl[42].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_HEIGHT;
+ ext_ctrl[42].value = 0;
+
+ if (pCTX->hier_p_enable) {
+ ext_ctrl[43].id = V4L2_CID_CODEC_MFC5X_ENC_H264_HIER_P_ENABLE;
+ ext_ctrl[43].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE;
+ ext_ctrl[44].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER0_QP;
+ ext_ctrl[44].value = pCTX->hier_qp_value.t0_frame_qp;
+ ext_ctrl[45].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER1_QP;
+ ext_ctrl[45].value = pCTX->hier_qp_value.t2_frame_qp;
+ ext_ctrl[46].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER2_QP;
+ ext_ctrl[46].value = pCTX->hier_qp_value.t3_frame_qp;
+ } else {
+ ext_ctrl[43].id = V4L2_CID_CODEC_MFC5X_ENC_H264_HIER_P_ENABLE;
+ ext_ctrl[43].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE;
+ ext_ctrl[44].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER0_QP;
+ ext_ctrl[44].value = 0;
+ ext_ctrl[45].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER1_QP;
+ ext_ctrl[45].value = 0;
+ ext_ctrl[46].id = V4L2_CID_CODEC_MFC5X_ENC_H264_LAYER2_QP;
+ ext_ctrl[46].value = 0;
+ }
+#ifdef S3D_SUPPORT
+ if (pCTX->sei_info.sei_gen_enable) {
+ ext_ctrl[47].id = V4L2_CID_CODEC_FRAME_PACK_FRM0_FLAG;
+ ext_ctrl[47].value = pCTX->sei_info.curr_frame_frm0_flag;
+ ext_ctrl[48].id = V4L2_CID_CODEC_FRAME_PACK_ARRGMENT_TYPE;
+ ext_ctrl[48].value = pCTX->sei_info.frame_pack_arrgment_type;
+ } else {
+ ext_ctrl[47].id = V4L2_CID_CODEC_FRAME_PACK_FRM0_FLAG;
+ ext_ctrl[47].value = 0;
+ ext_ctrl[48].id = V4L2_CID_CODEC_FRAME_PACK_ARRGMENT_TYPE;
+ ext_ctrl[48].value = 3;
+ }
+#else
+ ext_ctrl[47].id = V4L2_CID_CODEC_FRAME_PACK_FRM0_FLAG;
+ ext_ctrl[47].value = 0;
+ ext_ctrl[48].id = V4L2_CID_CODEC_FRAME_PACK_ARRGMENT_TYPE;
+ ext_ctrl[48].value = 3;
+#endif
+#if defined (MFC5x_VERSION)
+ ext_ctrl[49].id = V4L2_CID_CODEC_MFC5X_ENC_RC_FIXED_TARGET_BIT; /* MFC5.x Only */
+ ext_ctrl[49].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE;
+#elif defined (MFC6x_VERSION)
+ if (pCTX->fmo_enable) {
+ ext_ctrl[49].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_ENABLE;
+ ext_ctrl[49].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE;
+ ext_ctrl[50].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_MAP_TYPE;
+ ext_ctrl[50].value = pCTX->fmo_value.slice_map_type;
+ ext_ctrl[51].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SLICE_NUM;
+ ext_ctrl[51].value = pCTX->fmo_value.slice_num_grp;
+ if (pCTX->fmo_value.slice_map_type == 0) {
+ ext_ctrl[52].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN1;
+ ext_ctrl[53].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN2;
+ ext_ctrl[54].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN3;
+ ext_ctrl[55].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN4;
+ for (i = 0; i < pCTX->fmo_value.slice_num_grp; i++)
+ ext_ctrl[52+i].value = pCTX->fmo_value.run_length[i];
+ for (i = pCTX->fmo_value.slice_num_grp; i < 4; i++);
+ ext_ctrl[52+i].value = 1;
+ } else {
+ ext_ctrl[52].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN1;
+ ext_ctrl[52].value = 1;
+ ext_ctrl[53].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN2;
+ ext_ctrl[53].value = 1;
+ ext_ctrl[54].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN3;
+ ext_ctrl[54].value = 1;
+ ext_ctrl[55].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN4;
+ ext_ctrl[55].value = 1;
+ }
+ if (pCTX->fmo_value.slice_map_type == 4 || pCTX->fmo_value.slice_map_type == 5) {
+ ext_ctrl[56].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_DIR;
+ ext_ctrl[56].value = pCTX->fmo_value.sg_dir;
+ ext_ctrl[57].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_RATE;
+ ext_ctrl[57].value = pCTX->fmo_value.sg_rate;
+ } else {
+ ext_ctrl[56].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_DIR;
+ ext_ctrl[56].value = 0;
+ ext_ctrl[57].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_RATE;
+ ext_ctrl[57].value = 1;
+ }
+ } else {
+ ext_ctrl[49].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_ENABLE;
+ ext_ctrl[49].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE;
+ ext_ctrl[50].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_MAP_TYPE;
+ ext_ctrl[50].value = 0;
+ ext_ctrl[51].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SLICE_NUM;
+ ext_ctrl[51].value = 1;
+ ext_ctrl[52].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN1;
+ ext_ctrl[52].value = 1;
+ ext_ctrl[53].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN2;
+ ext_ctrl[53].value = 1;
+ ext_ctrl[54].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN3;
+ ext_ctrl[54].value = 1;
+ ext_ctrl[55].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_RUN_LEN4;
+ ext_ctrl[55].value = 1;
+ ext_ctrl[56].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_DIR;
+ ext_ctrl[56].value = 0;
+ ext_ctrl[57].id = V4L2_CID_CODEC_MFC5X_ENC_H264_FMO_SG_RATE;
+ ext_ctrl[57].value = 1;
+ }
+ if (pCTX->aso_enable) {
+ ext_ctrl[58].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_ENABLE;
+ ext_ctrl[58].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE;
+ ext_ctrl[59].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_0;
+ ext_ctrl[59].value = pCTX->aso_sl_order[0];
+ ext_ctrl[60].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_1;
+ ext_ctrl[60].value = pCTX->aso_sl_order[1];
+ ext_ctrl[61].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_2;
+ ext_ctrl[61].value = pCTX->aso_sl_order[2];
+ ext_ctrl[62].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_3;
+ ext_ctrl[62].value = pCTX->aso_sl_order[3];
+ ext_ctrl[63].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_4;
+ ext_ctrl[63].value = pCTX->aso_sl_order[4];
+ ext_ctrl[64].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_5;
+ ext_ctrl[64].value = pCTX->aso_sl_order[5];
+ ext_ctrl[65].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_6;
+ ext_ctrl[65].value = pCTX->aso_sl_order[6];
+ ext_ctrl[66].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_7;
+ ext_ctrl[66].value = pCTX->aso_sl_order[7];
+ } else {
+ ext_ctrl[58].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_ENABLE;
+ ext_ctrl[58].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE;
+ ext_ctrl[59].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_0;
+ ext_ctrl[59].value = 0;
+ ext_ctrl[60].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_1;
+ ext_ctrl[60].value = 0;
+ ext_ctrl[61].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_2;
+ ext_ctrl[61].value = 0;
+ ext_ctrl[62].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_3;
+ ext_ctrl[62].value = 0;
+ ext_ctrl[63].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_4;
+ ext_ctrl[63].value = 0;
+ ext_ctrl[64].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_5;
+ ext_ctrl[64].value = 0;
+ ext_ctrl[65].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_6;
+ ext_ctrl[65].value = 0;
+ ext_ctrl[66].id = V4L2_CID_CODEC_MFC5X_ENC_H264_ASO_SL_ORDER_7;
+ ext_ctrl[66].value = 0;
+ }
+#endif
+ break;
+
+ default:
+ LOGE("[%s] Undefined codec type",__func__);
+ ret = MFC_RET_INVALID_PARAM;
+ goto error_case1;
+ }
+
+ ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_CODEC;
+ if (pCTX->codecType == MPEG4_ENC) {
+ ext_ctrls.count = MPEG4_CTRL_NUM;
+ ext_ctrls.controls = ext_ctrl_mpeg4;
+ } else if (pCTX->codecType == H264_ENC) {
+ ext_ctrls.count = H264_CTRL_NUM;
+ ext_ctrls.controls = ext_ctrl;
+ } else if (pCTX->codecType == H263_ENC) {
+ ext_ctrls.count = H263_CTRL_NUM;
+ ext_ctrls.controls = ext_ctrl_h263;
+ }
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_S_EXT_CTRLS, &ext_ctrls);
+ if (ret != 0) {
+ LOGE("[%s] Failed to set extended controls",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+
+ fmt.fmt.pix_mp.width = pCTX->width;
+ fmt.fmt.pix_mp.height = pCTX->height;
+ fmt.fmt.pix_mp.num_planes = 2;
+#if 0
+ fmt.fmt.pix_mp.plane_fmt[0].bytesperline = Align(fmt.fmt.pix_mp.width, 128);
+ fmt.fmt.pix_mp.plane_fmt[1].bytesperline = Align(fmt.fmt.pix_mp.width, 128);
+
+ if (NV12_TILE == pCTX->framemap) {
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT; /* 4:2:0, 2 Planes, 64x32 Tiles */
+ fmt.fmt.pix_mp.plane_fmt[0].sizeimage =
+ Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height, 32), 8192); /* tiled mode */
+ fmt.fmt.pix_mp.plane_fmt[1].sizeimage =
+ Align(Align(fmt.fmt.pix_mp.width, 128) * Align(fmt.fmt.pix_mp.height >> 1, 32), 8192); /* tiled mode */
+ } else { /* NV12_LINEAR (default) */
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; /* 4:2:0, 2 Planes, linear */
+ fmt.fmt.pix_mp.plane_fmt[0].sizeimage =
+ Align((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height), 2048); /* linear mode, 2K align */
+ fmt.fmt.pix_mp.plane_fmt[1].sizeimage =
+ Align((fmt.fmt.pix_mp.width * (fmt.fmt.pix_mp.height >> 1)), 2048); /* linear mode, 2K align */
+ }
+#else /* FIXME: */
+ if (NV12_TILE == pCTX->framemap) {
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16; /* 4:2:0, 2 Planes, 16x16 Tiles */
+ } else { /* NV12_LINEAR (default) */
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; /* 4:2:0, 2 Planes, linear */
+ }
+#endif
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt);
+ if (ret != 0) {
+ LOGE("[%s] S_FMT failed on MFC output stream",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ /* capture (dst) */
+ memset(&fmt, 0, sizeof(fmt));
+
+ switch (pCTX->codecType) {
+ case H264_ENC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+ break;
+ case MPEG4_ENC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_MPEG4;
+ break;
+ case H263_ENC:
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H263;
+ break;
+ default:
+ LOGE("[%s] Codec has not been recognised",__func__);
+ return MFC_RET_ENC_INIT_FAIL;
+ }
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_STREAM_SIZE;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt);
+ if (ret != 0) {
+ LOGE("[%s] S_FMT failed on MFC output stream",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ /* cacheable buffer */
+ ctrl.id = V4L2_CID_CACHEABLE;
+ if (pCTX->cacheablebuffer == NO_CACHE)
+ ctrl.value = 0;
+ else
+ ctrl.value = 1;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CACHEABLE",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ /* Initialize streams for input */
+ memset(&reqbuf, 0, sizeof(reqbuf));
+ reqbuf.count = MFC_ENC_NUM_SRC_BUFS;
+ reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ if (pCTX->v4l2_enc.bInputPhyVir)
+ reqbuf.memory = V4L2_MEMORY_USERPTR;
+ else
+ reqbuf.memory = V4L2_MEMORY_MMAP;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf);
+ if (ret != 0) {
+ LOGE("[%s] Reqbufs src ioctl failed",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case1;
+ }
+ pCTX->v4l2_enc.mfc_num_src_bufs = reqbuf.count;
+
+ if (!pCTX->v4l2_enc.bInputPhyVir) {
+ /* Then the buffers have to be queried and mmaped */
+ for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; ++i) {
+ memset(&buf, 0, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = i;
+ buf.m.planes = planes;
+ buf.length = 2;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf);
+ if (ret != 0) {
+ LOGE("[%s] Querybuf src ioctl failed",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case2;
+ }
+
+ pCTX->v4l2_enc.mfc_src_bufs_len[0] = buf.m.planes[0].length;
+ pCTX->v4l2_enc.mfc_src_bufs_len[1] = buf.m.planes[1].length;
+
+ pCTX->v4l2_enc.mfc_src_phys[i][0] = buf.m.planes[0].cookie;
+ pCTX->v4l2_enc.mfc_src_phys[i][1] = buf.m.planes[1].cookie;
+
+ pCTX->v4l2_enc.mfc_src_bufs[i][0] =
+ mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE,
+ MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset);
+ if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == MAP_FAILED) {
+ LOGE("[%s] Mmap on src buffer (0) failed",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case2;
+ }
+
+ pCTX->v4l2_enc.mfc_src_bufs[i][1] =
+ mmap(NULL, buf.m.planes[1].length, PROT_READ | PROT_WRITE,
+ MAP_SHARED, pCTX->hMFC, buf.m.planes[1].m.mem_offset);
+ if (pCTX->v4l2_enc.mfc_src_bufs[i][1] == MAP_FAILED) {
+ munmap(pCTX->v4l2_enc.mfc_src_bufs[i][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]);
+ LOGE("[%s] Mmap on src buffer (1) failed",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case2;
+ }
+ }
+ } else
+ LOGV("[%s] Camera Phys src buf %d",__func__,reqbuf.count);
+
+ for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++)
+ pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_DEQUEUED;
+
+ pCTX->v4l2_enc.beingUsedIndex = 0;
+
+ pCTX->sizeFrmBuf.luma = (unsigned int)(pCTX->width * pCTX->height);
+ pCTX->sizeFrmBuf.chroma = (unsigned int)((pCTX->width * pCTX->height) >> 1);
+ pCTX->inter_buff_status |= MFC_USE_YUV_BUFF;
+
+ /* Initialize stream for output */
+ memset(&reqbuf, 0, sizeof(reqbuf));
+ reqbuf.count = MFC_ENC_MAX_DST_BUFS;
+ reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ reqbuf.memory = V4L2_MEMORY_MMAP;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf);
+ if (ret != 0) {
+ LOGE("[%s] Reqbufs dst ioctl failed",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case2;
+ }
+
+ pCTX->v4l2_enc.mfc_num_dst_bufs = reqbuf.count;
+
+ for (i = 0; i < MFC_ENC_MAX_DST_BUFS; ++i) {
+ memset(&buf, 0, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = i;
+ buf.m.planes = planes;
+ buf.length = 1;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf);
+ if (ret != 0) {
+ LOGE("[%s] Querybuf dst ioctl failed",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case3;
+ }
+
+ pCTX->v4l2_enc.mfc_dst_bufs_len = buf.m.planes[0].length;
+ pCTX->v4l2_enc.mfc_dst_bufs[i] =
+ mmap(NULL, buf.m.planes[0].length, PROT_READ | PROT_WRITE,
+ MAP_SHARED, pCTX->hMFC, buf.m.planes[0].m.mem_offset);
+ if (pCTX->v4l2_enc.mfc_dst_bufs[i] == MAP_FAILED) {
+ LOGE("[%s] Mmap on dst buffer failed",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case3;
+ }
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case3;
+ }
+ }
+
+ pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE;
+ pCTX->inter_buff_status |= MFC_USE_STRM_BUFF;
+
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type);
+ if (ret != 0) {
+ LOGE("[%s] V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, VIDIOC_STREAMON failed",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case3;
+ }
+
+ pCTX->inter_buff_status |= MFC_USE_DST_STREAMON;
+
+ memset(&buf, 0, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.m.planes = planes;
+ buf.length = 1;
+
+ /* note: #define POLLOUT 0x0004 */
+ poll_events.fd = pCTX->hMFC;
+ poll_events.events = POLLIN | POLLERR;
+ poll_events.revents = 0;
+
+ /* wait for header encoding */
+ do {
+ poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT);
+ if (0 < poll_state) {
+ if (poll_events.revents & POLLIN) { /* POLLIN */
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &buf);
+ if (ret == 0)
+ break;
+ } else if (poll_events.revents & POLLERR) { /*POLLERR */
+ LOGE("[%s] POLLERR\n",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case3;
+ } else {
+ LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case3;
+ }
+ } else if (0 > poll_state) {
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case3;
+ }
+ } while (1 == poll_state);
+
+ pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = buf.m.planes[0].bytesused;
+ pCTX->virStrmBuf = (unsigned int)pCTX->v4l2_enc.mfc_dst_bufs[buf.index];
+
+ /* stream dequeued index */
+ index = buf.index;
+ memset(&buf, 0, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = index;
+ buf.m.planes = planes;
+ buf.length = 1;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &buf);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__);
+ ret = MFC_RET_ENC_INIT_FAIL;
+ goto error_case3;
+ }
+ LOGV("[%s] Strm out idx %d",__func__,index);
+
+ return MFC_RET_OK;
+
+error_case3:
+ for (j = 0; j < i; j++)
+ munmap(pCTX->v4l2_enc.mfc_dst_bufs[j], pCTX->v4l2_enc.mfc_dst_bufs_len);
+
+ i = pCTX->v4l2_enc.mfc_num_src_bufs;
+error_case2:
+ if (!pCTX->v4l2_enc.bInputPhyVir) {
+ for (j = 0; j < i; j++) {
+ munmap(pCTX->v4l2_enc.mfc_src_bufs[j][0], pCTX->v4l2_enc.mfc_src_bufs_len[0]);
+ munmap(pCTX->v4l2_enc.mfc_src_bufs[j][1], pCTX->v4l2_enc.mfc_src_bufs_len[1]);
+ }
+ }
+error_case1:
+ return ret;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info)
+{
+ _MFCLIB *pCTX;
+ int i;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL\n",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ /* FIXME check this if GetInBuf() is not called for UserPtr */
+ if (pCTX->v4l2_enc.bInputPhyVir) {
+ input_info->YPhyAddr = (void*)0;
+ input_info->CPhyAddr = (void*)0;
+ input_info->YVirAddr = (void*)0;
+ input_info->CVirAddr = (void*)0;
+
+ /* FIXME check whether Y & C sizes should be set or not*/
+ if (NV12_TILE == pCTX->framemap) {
+ /* 4:2:0, 2 Planes, 64x32 Tiles */
+ input_info->YSize = Align(Align(pCTX->width, 128) * Align(pCTX->height, 32), 8192); /* tiled mode */
+ input_info->CSize = Align(Align(pCTX->width, 128) * Align(pCTX->height >> 1, 32), 8192); /* tiled mode */
+ } else { /* NV12_LINEAR (default) */
+ /* 4:2:0, 2 Planes, linear */
+ input_info->YSize = Align(Align(pCTX->width, 16) * Align(pCTX->height, 16), 2048); /* width = 16B, height = 16B align */
+ input_info->CSize = Align(Align(pCTX->width, 16) * Align(pCTX->height >> 1, 8), 2048); /* width = 16B, height = 8B align */
+ }
+ } else {
+ for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++)
+ if (BUF_DEQUEUED == pCTX->v4l2_enc.mfc_src_buf_flags[i])
+ break;
+
+ if (i == pCTX->v4l2_enc.mfc_num_src_bufs) {
+ LOGV("[%s] No buffer is available.",__func__);
+ return MFC_RET_ENC_GET_INBUF_FAIL;
+ } else {
+ input_info->YPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][0];
+ input_info->CPhyAddr = (void*)pCTX->v4l2_enc.mfc_src_phys[i][1];
+ input_info->YVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][0];
+ input_info->CVirAddr = (void*)pCTX->v4l2_enc.mfc_src_bufs[i][1];
+ input_info->YSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[0];
+ input_info->CSize = (int)pCTX->v4l2_enc.mfc_src_bufs_len[1];
+
+ pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED;
+ }
+ }
+ LOGV("[%s] Input Buffer idx %d",__func__,i);
+ return MFC_RET_OK;
+}
+
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info)
+{
+ _MFCLIB *pCTX;
+ struct v4l2_buffer qbuf;
+ struct v4l2_plane planes[MFC_ENC_NUM_PLANES];
+ int ret,i;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL\n",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ memset(&qbuf, 0, sizeof(qbuf));
+ if (pCTX->v4l2_enc.bInputPhyVir) {
+ qbuf.memory = V4L2_MEMORY_USERPTR;
+ qbuf.index = pCTX->v4l2_enc.beingUsedIndex;
+ planes[0].m.userptr = (unsigned long)input_info->YPhyAddr;
+ planes[0].length = input_info->YSize;
+ planes[0].bytesused = input_info->YSize;
+ planes[1].m.userptr = (unsigned long)input_info->CPhyAddr;
+ planes[1].length = input_info->CSize;
+ planes[1].bytesused = input_info->CSize;
+
+ /* FIXME, this is only for case of not using B frame,
+ Camera side should know which buffer is queued() refering to index of
+ MFC dqbuf() */
+ pCTX->v4l2_enc.beingUsedIndex++;
+ pCTX->v4l2_enc.beingUsedIndex %= MFC_ENC_NUM_SRC_BUFS;
+ LOGV("[%s] Phy Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex);
+ } else {
+ for (i = 0; i < pCTX->v4l2_enc.mfc_num_src_bufs; i++)
+ if (pCTX->v4l2_enc.mfc_src_bufs[i][0] == input_info->YVirAddr)
+ break;
+
+ if (i == pCTX->v4l2_enc.mfc_num_src_bufs) {
+ LOGE("[%s] Can not use the buffer",__func__);
+ return MFC_RET_INVALID_PARAM;
+ } else {
+ pCTX->v4l2_enc.beingUsedIndex = i;
+ //pCTX->v4l2_enc.mfc_src_buf_flags[i] = BUF_ENQUEUED;
+ }
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.index = pCTX->v4l2_enc.beingUsedIndex;
+ planes[0].bytesused = pCTX->width * pCTX->height;
+ planes[1].bytesused = (pCTX->width * pCTX->height) >> 1;
+ LOGV("[%s] Input Buffer idx Queued %d",__func__,pCTX->v4l2_enc.beingUsedIndex);
+ }
+
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ qbuf.m.planes = planes;
+ qbuf.length = 2;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__);
+ return MFC_RET_ENC_SET_INBUF_FAIL;
+ }
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info)
+{
+ _MFCLIB *pCTX;
+ struct v4l2_control ctrl;
+ unsigned int encoded_y_addr, encoded_c_addr;
+ int ret;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL\n",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ if (pCTX->v4l2_enc.bRunning == 0) {
+ pCTX->encodedHeaderSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len;
+ output_info->dataSize = 0;
+ } else {
+ output_info->dataSize = pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len;
+ }
+
+ ctrl.id = V4L2_CID_CODEC_ENCODED_LUMA_ADDR;
+ ctrl.value = 0;
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl);
+ if (ret != 0)
+ LOGE("[%s] Error to do g_ctrl",__func__);
+ encoded_y_addr = (unsigned int)ctrl.value;
+
+ ctrl.id = V4L2_CID_CODEC_ENCODED_CHROMA_ADDR;
+ ctrl.value = 0;
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl);
+ if (ret != 0)
+ LOGE("[%s] Error to do g_ctrl",__func__);
+ encoded_c_addr = (unsigned int)ctrl.value;
+
+ output_info->headerSize = pCTX->encodedHeaderSize;
+ output_info->frameType = pCTX->encodedframeType;
+ output_info->StrmPhyAddr = (void *)0;
+ output_info->StrmVirAddr = (void *)pCTX->virStrmBuf;
+ output_info->encodedYPhyAddr = (void*)encoded_y_addr;
+ output_info->encodedCPhyAddr = (void*)encoded_c_addr;
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize)
+{
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL\n",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ return MFC_RET_ENC_SET_OUTBUF_FAIL;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle)
+{
+ int ret;
+ int dequeued_index;
+ int loopcnt = 0;
+ _MFCLIB *pCTX;
+
+ struct v4l2_buffer qbuf;
+ struct v4l2_plane planes[MFC_ENC_NUM_PLANES];
+ enum v4l2_buf_type type;
+
+ struct v4l2_control ctrl;
+
+ struct pollfd poll_events;
+ int poll_state;
+
+ LOGV("[%s] Enter \n",__func__);
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL\n",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ ctrl.id = V4L2_CID_CODEC_FRAME_TAG;
+ ctrl.value = pCTX->inframetag;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_S_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__);
+ return MFC_RET_ENC_EXE_ERR;
+ }
+
+ if (pCTX->v4l2_enc.bRunning == 0) {
+ type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_STREAMON failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__);
+ return MFC_RET_ENC_EXE_ERR;
+ }
+
+ pCTX->v4l2_enc.bRunning = 1;
+ }
+
+ pCTX->inter_buff_status |= MFC_USE_SRC_STREAMON;
+
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.m.planes = planes;
+ qbuf.length = 1;
+
+ /* note: #define POLLOUT 0x0004 */
+ poll_events.fd = pCTX->hMFC;
+ poll_events.events = POLLIN | POLLERR;
+ poll_events.revents = 0;
+
+ /* wait for encoding */
+ do {
+ poll_state = poll((struct pollfd*)&poll_events, 1, POLL_ENC_WAIT_TIMEOUT);
+ if (0 < poll_state) {
+ if (poll_events.revents & POLLIN) { /* POLLIN */
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+ if (ret == 0)
+ break;
+ } else if (poll_events.revents & POLLERR) { /* POLLERR */
+ LOGE("[%s] POLLERR\n",__func__);
+ return MFC_RET_ENC_EXE_ERR;
+ } else {
+ LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents);
+ return MFC_RET_ENC_EXE_ERR;
+ }
+ } else if (0 > poll_state) {
+ LOGE("[%s] poll() Encoder POLL Timeout 0x%x\n",__func__, poll_events.revents);
+ return MFC_RET_ENC_EXE_ERR;
+ } else { /* in the case of B frame encoding */
+ ctrl.id = V4L2_CID_CODEC_CHECK_STATE;
+ ctrl.value = 0;
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl);
+ LOGV("[%s] ctx state = %d\n",__func__, ctrl.value);
+ if (ctrl.value == MFCSTATE_ENC_NO_OUTPUT)
+ return MFC_RET_OK;
+ }
+ loopcnt++;
+ } while ((0 == poll_state) && (loopcnt < 5));
+
+ if (pCTX->v4l2_enc.bRunning != 0) {
+ pCTX->encodedframeType = (qbuf.flags & 0x38) >> 3; /* encoded frame type */
+ LOGV("[%s] encoded frame type = %d\n", __func__, pCTX->encodedframeType);
+
+ switch (pCTX->encodedframeType) {
+ case 1:
+ pCTX->encodedframeType = MFC_FRAME_TYPE_I_FRAME;
+ break;
+ case 2:
+ pCTX->encodedframeType = MFC_FRAME_TYPE_P_FRAME;
+ break;
+ case 4:
+ pCTX->encodedframeType = MFC_FRAME_TYPE_B_FRAME;
+ break;
+ default:
+ LOGE("[%s] VIDIOC_DQBUF failed, encoded frame type is wrong",__func__);
+ }
+ }
+
+ dequeued_index = qbuf.index;
+
+ if (qbuf.m.planes[0].bytesused > 0) { /* FIXME later */
+ pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = qbuf.m.planes[0].bytesused;
+ }
+
+ ctrl.id = V4L2_CID_CODEC_FRAME_TAG;
+ ctrl.value = 0;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_FRAME_TAG",__func__);
+ return MFC_RET_ENC_EXE_ERR;
+ }
+
+ pCTX->outframetagtop = ctrl.value;
+
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.index = dequeued_index;
+ qbuf.m.planes = planes;
+ qbuf.length = 1;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE",__func__);
+ return MFC_RET_ENC_EXE_ERR;
+ }
+
+ if (pCTX->v4l2_enc.bRunning != 0) {
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+
+ if (pCTX->v4l2_enc.bInputPhyVir)
+ qbuf.memory = V4L2_MEMORY_USERPTR;
+ else
+ qbuf.memory = V4L2_MEMORY_MMAP;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_DQBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__);
+ return MFC_RET_ENC_EXE_ERR;
+ }
+ }
+ pCTX->v4l2_enc.mfc_src_buf_flags[qbuf.index] = BUF_DEQUEUED;
+
+ /* Update context stream buffer address */
+ pCTX->virStrmBuf = (unsigned int)pCTX->v4l2_enc.mfc_dst_bufs[dequeued_index];
+ LOGV("[%s] Strm out idx %d",__func__,dequeued_index);
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value)
+{
+ _MFCLIB *pCTX;
+ struct v4l2_control ctrl;
+ struct mfc_enc_hier_p_qp hier_p_qp;
+#ifdef S3D_SUPPORT
+ SSBSIP_MFC_FRAME_PACKING *frame_packing;
+#endif
+ struct mfc_enc_fmo fmo_param;
+ int *aso_param;
+ int ret, i;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL\n",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if (value == NULL) {
+ LOGE("[%s] value is NULL\n",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ switch (conf_type) {
+ case MFC_ENC_SETCONF_FRAME_TAG:
+ pCTX->inframetag = *((unsigned int *)value);
+ return MFC_RET_OK;
+
+ case MFC_ENC_SETCONF_FRAME_TYPE:
+ ctrl.id = V4L2_CID_CODEC_FRAME_INSERTION;
+ ctrl.value = *((unsigned int*)value);
+ break;
+
+ case MFC_ENC_SETCONF_I_PERIOD:
+ ctrl.id = V4L2_CID_CODEC_ENCODED_I_PERIOD_CH;
+ ctrl.value = *((unsigned int*)value);
+ break;
+
+ case MFC_ENC_SETCONF_CHANGE_FRAME_RATE:
+ ctrl.id = V4L2_CID_CODEC_ENCODED_FRAME_RATE_CH;
+ ctrl.value = *((unsigned int*)value);
+ break;
+
+ case MFC_ENC_SETCONF_CHANGE_BIT_RATE:
+ ctrl.id = V4L2_CID_CODEC_ENCODED_BIT_RATE_CH;
+ ctrl.value = *((unsigned int*)value);
+ break;
+#ifdef S3D_SUPPORT
+ case MFC_ENC_SETCONF_SEI_GEN:
+ ctrl.id = V4L2_CID_CODEC_FRAME_PACK_SEI_GEN;
+ ctrl.value = *((unsigned int*)value);
+ pCTX->sei_info.sei_gen_enable = 1;
+ break;
+#endif
+ case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP:
+ pCTX->enc_frameskip = *((int *)value);
+ return MFC_RET_OK;
+#if 0
+ case MFC_ENC_SETCONF_VUI_INFO:
+ vui_info = *((struct mfc_enc_vui_info *) value);
+ EncArg.args.set_config.in_config_value[0] = (int)(vui_info.aspect_ratio_idc);
+ EncArg.args.set_config.in_config_value[1] = 0;
+ break;
+#endif
+ case MFC_ENC_SETCONF_HIER_P:
+ hier_p_qp = *((struct mfc_enc_hier_p_qp *) value);
+ pCTX->hier_p_enable = 1;
+ pCTX->hier_qp_value.t0_frame_qp = (int)(hier_p_qp.t0_frame_qp);
+ pCTX->hier_qp_value.t2_frame_qp = (int)(hier_p_qp.t2_frame_qp);
+ pCTX->hier_qp_value.t3_frame_qp = (int)(hier_p_qp.t3_frame_qp);
+ return MFC_RET_OK;
+#ifdef S3D_SUPPORT
+ case MFC_ENC_SETCONF_FRAME_PACKING:
+ frame_packing = (SSBSIP_MFC_FRAME_PACKING *)value;
+ pCTX->sei_info.curr_frame_frm0_flag = (int)(frame_packing->current_frame_is_frame0_flag);
+ pCTX->sei_info.frame_pack_arrgment_type = (int)(frame_packing->arrangement_type);
+ return MFC_RET_OK;
+#endif
+ case MFC_ENC_SETCONF_FMO:
+ fmo_param = *((struct mfc_enc_fmo *) value);
+ pCTX->fmo_enable = 1;
+ pCTX->fmo_value.slice_map_type = (int)(fmo_param.slice_map_type);
+ pCTX->fmo_value.slice_num_grp = (int)(fmo_param.slice_num_grp);
+ pCTX->fmo_value.run_length[0] = (int)(fmo_param.run_length[0]);
+ pCTX->fmo_value.run_length[1] = (int)(fmo_param.run_length[1]);
+ pCTX->fmo_value.run_length[2] = (int)(fmo_param.run_length[2]);
+ pCTX->fmo_value.run_length[3] = (int)(fmo_param.run_length[3]);
+ pCTX->fmo_value.sg_dir = (int)(fmo_param.sg_dir);
+ pCTX->fmo_value.sg_rate = (int)(fmo_param.sg_rate);
+ return MFC_RET_OK;
+
+ case MFC_ENC_SETCONF_ASO:
+ aso_param = (int *) value;
+ pCTX->aso_enable = 1;
+ for (i = 0; i < 8; i++)
+ pCTX->aso_sl_order[i] = (int)aso_param[i];
+ return MFC_RET_OK;
+
+ default:
+ LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_S_CTRL, &ctrl);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_S_CTRL failed (conf_type = %d)",__func__, conf_type);
+ return MFC_RET_ENC_SET_CONF_FAIL;
+ }
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value)
+{
+ _MFCLIB *pCTX;
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL\n",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if (value == NULL) {
+ LOGE("[%s] value is NULL\n",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ switch (conf_type) {
+ case MFC_ENC_GETCONF_FRAME_TAG:
+ *((unsigned int *)value) = pCTX->outframetagtop;
+ break;
+
+ default:
+ LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ return MFC_RET_OK;
+}
+
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h
new file mode 100644
index 0000000..b386c72
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/SsbSipMfcApi.h
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Global header for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _SSBSIP_MFC_API_H_
+#define _SSBSIP_MFC_API_H_
+
+/*--------------------------------------------------------------------------------*/
+/* Definition */
+/*--------------------------------------------------------------------------------*/
+#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072)
+#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072)
+
+#define MFC6x_VERSION
+
+#define SUPPORT_1080P 1
+
+#if SUPPORT_1080P
+#define MMAP_BUFFER_SIZE_MMAP (70*1024*1024) /* only C110 use this value. in C210, memory size is decided in menuconfig*/
+#else
+#define MMAP_BUFFER_SIZE_MMAP (62*1024*1024)
+#endif
+
+#define SAMSUNG_MFC_DEV_NAME "/dev/video"
+
+#define SSBSIP_MFC_OK (1)
+#define SSBSIP_MFC_FAIL (0)
+
+/*--------------------------------------------------------------------------------*/
+/* Structure and Type */
+/*--------------------------------------------------------------------------------*/
+typedef enum {
+ H264_DEC,
+ VC1_DEC, /* VC1 advaced Profile decoding */
+ MPEG4_DEC,
+ XVID_DEC,
+ MPEG1_DEC,
+ MPEG2_DEC,
+ H263_DEC,
+ VC1RCV_DEC, /* VC1 simple/main profile decoding */
+ FIMV1_DEC,
+ FIMV2_DEC,
+ FIMV3_DEC,
+ FIMV4_DEC,
+#if defined (MFC6x_VERSION)
+ VP8_DEC,
+#endif
+ H264_ENC,
+ MPEG4_ENC,
+ H263_ENC,
+ UNKNOWN_TYPE
+} SSBSIP_MFC_CODEC_TYPE;
+
+typedef enum {
+ DONT_CARE = 0,
+ I_FRAME = 1,
+ NOT_CODED = 2
+} SSBSIP_MFC_FORCE_SET_FRAME_TYPE;
+
+typedef enum {
+ NV12_LINEAR = 0,
+ NV12_TILE,
+ NV21_LINEAR
+} SSBSIP_MFC_INSTRM_MODE_TYPE;
+
+typedef enum {
+ FRAME = 0,
+ SLICE,
+} SSBSIP_MFC_OUTSTRM_MODE_TYPE;
+
+typedef enum {
+ NO_CACHE = 0,
+ CACHE = 1
+} SSBIP_MFC_BUFFER_TYPE;
+
+typedef enum {
+ MFC_DEC_SETCONF_POST_ENABLE = 1,
+ MFC_DEC_SETCONF_EXTRA_BUFFER_NUM,
+ MFC_DEC_SETCONF_DISPLAY_DELAY,
+ MFC_DEC_SETCONF_IS_LAST_FRAME,
+ MFC_DEC_SETCONF_SLICE_ENABLE,
+ MFC_DEC_SETCONF_CRC_ENABLE,
+ MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT,
+ MFC_DEC_SETCONF_FRAME_TAG,
+ MFC_DEC_GETCONF_CRC_DATA,
+ MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT,
+ MFC_DEC_GETCONF_CROP_INFO,
+ MFC_DEC_GETCONF_FRAME_TAG,
+
+ /* C210 specific feature */
+ MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY,
+ MFC_DEC_SETCONF_DPB_FLUSH,
+ MFC_DEC_SETCONF_PIXEL_CACHE,
+ MFC_DEC_GETCONF_WIDTH_HEIGHT,
+#ifdef S3D_SUPPORT
+ /* S3D specific feature */
+ MFC_DEC_SETCONF_SEI_PARSE,
+ MFC_DEC_GETCONF_FRAME_PACKING
+#endif
+} SSBSIP_MFC_DEC_CONF;
+
+typedef enum {
+ MFC_ENC_SETCONF_FRAME_TYPE = 100,
+ MFC_ENC_SETCONF_CHANGE_FRAME_RATE,
+ MFC_ENC_SETCONF_CHANGE_BIT_RATE,
+ MFC_ENC_SETCONF_FRAME_TAG,
+ MFC_ENC_SETCONF_ALLOW_FRAME_SKIP,
+ MFC_ENC_GETCONF_FRAME_TAG,
+
+ /* C210 specific feature */
+ MFC_ENC_SETCONF_VUI_INFO,
+ MFC_ENC_SETCONF_I_PERIOD,
+ MFC_ENC_SETCONF_HIER_P,
+#ifdef S3D_SUPPORT
+ /* S3D Specific feature */
+ MFC_ENC_SETCONF_SEI_GEN,
+ MFC_ENC_SETCONF_FRAME_PACKING,
+#endif
+ MFC_ENC_SETCONF_FMO,
+ MFC_ENC_SETCONF_ASO,
+} SSBSIP_MFC_ENC_CONF;
+
+typedef enum {
+ MFC_GETOUTBUF_STATUS_NULL = 0,
+ MFC_GETOUTBUF_DECODING_ONLY = 1,
+ MFC_GETOUTBUF_DISPLAY_DECODING,
+ MFC_GETOUTBUF_DISPLAY_ONLY,
+ MFC_GETOUTBUF_DISPLAY_END,
+ MFC_GETOUTBUF_CHANGE_RESOL
+} SSBSIP_MFC_DEC_OUTBUF_STATUS;
+
+typedef enum {
+ MFC_FRAME_TYPE_NOT_CODED,
+ MFC_FRAME_TYPE_I_FRAME,
+ MFC_FRAME_TYPE_P_FRAME,
+ MFC_FRAME_TYPE_B_FRAME,
+ MFC_FRAME_TYPE_OTHERS
+} SSBSIP_MFC_FRAME_TYPE;
+
+typedef enum {
+ MFC_RET_OK = 1,
+ MFC_RET_FAIL = -1000,
+ MFC_RET_OPEN_FAIL = -1001,
+ MFC_RET_CLOSE_FAIL = -1002,
+
+ MFC_RET_DEC_INIT_FAIL = -2000,
+ MFC_RET_DEC_EXE_TIME_OUT = -2001,
+ MFC_RET_DEC_EXE_ERR = -2002,
+ MFC_RET_DEC_GET_INBUF_FAIL = -2003,
+ MFC_RET_DEC_SET_INBUF_FAIL = -2004,
+ MFC_RET_DEC_GET_OUTBUF_FAIL = -2005,
+ MFC_RET_DEC_GET_CONF_FAIL = -2006,
+ MFC_RET_DEC_SET_CONF_FAIL = -2007,
+
+ MFC_RET_ENC_INIT_FAIL = -3000,
+ MFC_RET_ENC_EXE_TIME_OUT = -3001,
+ MFC_RET_ENC_EXE_ERR = -3002,
+ MFC_RET_ENC_GET_INBUF_FAIL = -3003,
+ MFC_RET_ENC_SET_INBUF_FAIL = -3004,
+ MFC_RET_ENC_GET_OUTBUF_FAIL = -3005,
+ MFC_RET_ENC_SET_OUTBUF_FAIL = -3006,
+ MFC_RET_ENC_GET_CONF_FAIL = -3007,
+ MFC_RET_ENC_SET_CONF_FAIL = -3008,
+
+ MFC_RET_INVALID_PARAM = -4000
+} SSBSIP_MFC_ERROR_CODE;
+
+typedef struct {
+ void *YPhyAddr; /* [OUT] physical address of Y */
+ void *CPhyAddr; /* [OUT] physical address of CbCr */
+ void *YVirAddr; /* [OUT] virtual address of Y */
+ void *CVirAddr; /* [OUT] virtual address of CbCr */
+
+ int img_width; /* [OUT] width of real image */
+ int img_height; /* [OUT] height of real image */
+ int buf_width; /* [OUT] width aligned to 16 */
+ int buf_height; /* [OUT] height alighed to 16 */
+
+ int timestamp_top; /* [OUT] timestamp of top filed(This is used for interlaced stream) */
+ int timestamp_bottom; /* [OUT] timestamp of bottom filed(This is used for interlaced stream) */
+ int consumedByte; /* [OUT] the number of byte consumed during decoding */
+ int res_change; /* [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased */
+ int crop_top_offset; /* [OUT] crop information, top_offset */
+ int crop_bottom_offset; /* [OUT] crop information, bottom_offset */
+ int crop_left_offset; /* [OUT] crop information, left_offset */
+ int crop_right_offset; /* [OUT] crop information, right_offset */
+ int disp_pic_frame_type; /* [OUT] display picture frame type information */
+
+ /* C210 UMP feature */
+ unsigned int y_cookie; /* [OUT] cookie for Y address */
+ unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */
+} SSBSIP_MFC_DEC_OUTPUT_INFO;
+
+typedef struct {
+ void *YPhyAddr; /* [IN/OUT] physical address of Y */
+ void *CPhyAddr; /* [IN/OUT] physical address of CbCr */
+ void *YVirAddr; /* [IN/OUT] virtual address of Y */
+ void *CVirAddr; /* [IN/OUT] virtual address of CbCr */
+ int YSize; /* [IN/OUT] input size of Y data */
+ int CSize; /* [IN/OUT] input size of CbCr data */
+
+ /* C210 UMP feature */
+ unsigned int y_cookie; /* [OUT] cookie for Y address */
+ unsigned int c_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */
+} SSBSIP_MFC_ENC_INPUT_INFO;
+
+typedef struct {
+ unsigned int dataSize; /* [OUT] encoded data size(without header) */
+ unsigned int headerSize; /* [OUT] encoded header size */
+ unsigned int frameType; /* [OUT] frame type of encoded stream */
+ void *StrmPhyAddr; /* [OUT] physical address of Y */
+ void *StrmVirAddr; /* [OUT] virtual address of Y */
+ void *encodedYPhyAddr; /* [OUT] physical address of Y which is flushed */
+ void *encodedCPhyAddr; /* [OUT] physical address of C which is flushed */
+
+ /* C210 UMP feature */
+ unsigned int strm_cookie; /* [OUT] cooke for stream buffer */
+ unsigned int y_encoded_cookie; /* [OUT] cookie for Y address */
+ unsigned int c_encoded_cookie; /* [OUT] cookie for CbCr address, If it is 0, Y and CbCr is in continous memory */
+} SSBSIP_MFC_ENC_OUTPUT_INFO;
+
+typedef struct {
+ /* common parameters */
+ SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */
+ int SourceWidth; /* [IN] width of video to be encoded */
+ int SourceHeight; /* [IN] height of video to be encoded */
+ int IDRPeriod; /* [IN] GOP number(interval of I-frame) */
+ int SliceMode; /* [IN] Multi slice mode */
+ int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */
+ int EnableFRMRateControl; /* [IN] frame based rate control enable */
+ int Bitrate; /* [IN] rate control parameter(bit rate) */
+ int FrameQp; /* [IN] The quantization parameter of the frame */
+ int FrameQp_P; /* [IN] The quantization parameter of the P frame */
+ int QSCodeMax; /* [IN] Maximum Quantization value */
+ int QSCodeMin; /* [IN] Minimum Quantization value */
+ int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */
+ int PadControlOn; /* [IN] Enable padding control */
+ int LumaPadVal; /* [IN] Luma pel value used to fill padding area */
+ int CbPadVal; /* [IN] CB pel value used to fill padding area */
+ int CrPadVal; /* [IN] CR pel value used to fill padding area */
+ int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */
+ SSBSIP_MFC_OUTSTRM_MODE_TYPE OutputMode; /* [IN] Output mode: Frame/Slice */
+
+ /* H.264 specific parameters */
+ int ProfileIDC; /* [IN] profile */
+ int LevelIDC; /* [IN] level */
+ int FrameQp_B; /* [IN] The quantization parameter of the B frame */
+ int FrameRate; /* [IN] rate control parameter(frame rate) */
+ int SliceArgument; /* [IN] MB number or byte number */
+ int NumberBFrames; /* [IN] The number of consecutive B frame inserted */
+ int NumberReferenceFrames; /* [IN] The number of reference pictures used */
+ int NumberRefForPframes; /* [IN] The number of reference pictures used for encoding P pictures */
+ int LoopFilterDisable; /* [IN] disable the loop filter */
+ int LoopFilterAlphaC0Offset; /* [IN] Alpha & C0 offset for H.264 loop filter */
+ int LoopFilterBetaOffset; /* [IN] Beta offset for H.264 loop filter */
+ int SymbolMode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */
+ int PictureInterlace; /* [IN] Enables the interlace mode */
+ int Transform8x8Mode; /* [IN] Allow 8x8 transform(This is allowed only for high profile) */
+ int EnableMBRateControl; /* [IN] Enable macroblock-level rate control */
+ int DarkDisable; /* [IN] Disable adaptive rate control on dark region */
+ int SmoothDisable; /* [IN] Disable adaptive rate control on smooth region */
+ int StaticDisable; /* [IN] Disable adaptive rate control on static region */
+ int ActivityDisable; /* [IN] Disable adaptive rate control on high activity region */
+} SSBSIP_MFC_ENC_H264_PARAM;
+
+typedef struct {
+ /* common parameters */
+ SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */
+ int SourceWidth; /* [IN] width of video to be encoded */
+ int SourceHeight; /* [IN] height of video to be encoded */
+ int IDRPeriod; /* [IN] GOP number(interval of I-frame) */
+ int SliceMode; /* [IN] Multi slice mode */
+ int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */
+ int EnableFRMRateControl; /* [IN] frame based rate control enable */
+ int Bitrate; /* [IN] rate control parameter(bit rate) */
+ int FrameQp; /* [IN] The quantization parameter of the frame */
+ int FrameQp_P; /* [IN] The quantization parameter of the P frame */
+ int QSCodeMax; /* [IN] Maximum Quantization value */
+ int QSCodeMin; /* [IN] Minimum Quantization value */
+ int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */
+ int PadControlOn; /* [IN] Enable padding control */
+ int LumaPadVal; /* [IN] Luma pel value used to fill padding area */
+ int CbPadVal; /* [IN] CB pel value used to fill padding area */
+ int CrPadVal; /* [IN] CR pel value used to fill padding area */
+ int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */
+ SSBSIP_MFC_OUTSTRM_MODE_TYPE OutputMode; /* [IN] Output mode: Frame/Slice */
+#if defined (MFC6x_VERSION)
+ int EnableMBRateControl; /* [IN] Enable macroblock-level rate control, MFC6.x Only */
+#endif
+
+ /* MPEG4 specific parameters */
+ int ProfileIDC; /* [IN] profile */
+ int LevelIDC; /* [IN] level */
+ int FrameQp_B; /* [IN] The quantization parameter of the B frame */
+ int TimeIncreamentRes; /* [IN] frame rate */
+ int VopTimeIncreament; /* [IN] frame rate */
+ int SliceArgument; /* [IN] MB number or byte number */
+ int NumberBFrames; /* [IN] The number of consecutive B frame inserted */
+ int DisableQpelME; /* [IN] disable quarter-pixel motion estimation */
+} SSBSIP_MFC_ENC_MPEG4_PARAM;
+
+typedef struct {
+ /* common parameters */
+ SSBSIP_MFC_CODEC_TYPE codecType; /* [IN] codec type */
+ int SourceWidth; /* [IN] width of video to be encoded */
+ int SourceHeight; /* [IN] height of video to be encoded */
+ int IDRPeriod; /* [IN] GOP number(interval of I-frame) */
+ int SliceMode; /* [IN] Multi slice mode */
+ int RandomIntraMBRefresh; /* [IN] cyclic intra refresh */
+ int EnableFRMRateControl; /* [IN] frame based rate control enable */
+ int Bitrate; /* [IN] rate control parameter(bit rate) */
+ int FrameQp; /* [IN] The quantization parameter of the frame */
+ int FrameQp_P; /* [IN] The quantization parameter of the P frame */
+ int QSCodeMax; /* [IN] Maximum Quantization value */
+ int QSCodeMin; /* [IN] Minimum Quantization value */
+ int CBRPeriodRf; /* [IN] Reaction coefficient parameter for rate control */
+ int PadControlOn; /* [IN] Enable padding control */
+ int LumaPadVal; /* [IN] Luma pel value used to fill padding area */
+ int CbPadVal; /* [IN] CB pel value used to fill padding area */
+ int CrPadVal; /* [IN] CR pel value used to fill padding area */
+ int FrameMap; /* [IN] Encoding input mode(tile mode or linear mode) */
+#if defined (MFC6x_VERSION)
+ int EnableMBRateControl; /* [IN] Enable macroblock-level rate control, MFC6.x Only */
+#endif
+
+ /* H.263 specific parameters */
+ int FrameRate; /* [IN] rate control parameter(frame rate) */
+} SSBSIP_MFC_ENC_H263_PARAM;
+
+typedef struct {
+ int width;
+ int height;
+ int buf_width;
+ int buf_height;
+} SSBSIP_MFC_IMG_RESOLUTION;
+
+typedef struct {
+ int crop_top_offset;
+ int crop_bottom_offset;
+ int crop_left_offset;
+ int crop_right_offset;
+} SSBSIP_MFC_CROP_INFORMATION;
+
+#ifdef S3D_SUPPORT
+typedef struct {
+ int available;
+ unsigned int arrangement_id;
+ int arrangement_cancel_flag;
+ unsigned char arrangement_type;
+ int quincunx_sampling_flag;
+ unsigned char content_interpretation_type;
+ int spatial_flipping_flag;
+ int frame0_flipped_flag;
+ int field_views_flag;
+ int current_frame_is_frame0_flag;
+ unsigned char frame0_grid_pos_x;
+ unsigned char frame0_grid_pos_y;
+ unsigned char frame1_grid_pos_x;
+ unsigned char frame1_grid_pos_y;
+} SSBSIP_MFC_FRAME_PACKING;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*--------------------------------------------------------------------------------*/
+/* Decoding APIs */
+/*--------------------------------------------------------------------------------*/
+void *SsbSipMfcDecOpen(void);
+void *SsbSipMfcDecOpenExt(void *value);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill);
+//SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle);
+void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize);
+//SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info);
+
+#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(USE_UMP))
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, unsigned int secure_id, int size);
+#else
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size);
+#endif
+
+SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info);
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value);
+
+/*--------------------------------------------------------------------------------*/
+/* Encoding APIs */
+/*--------------------------------------------------------------------------------*/
+void *SsbSipMfcEncOpen(void);
+void *SsbSipMfcEncOpenExt(void *value);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle);
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info);
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize);
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value);
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SSBSIP_MFC_API_H_ */
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h
new file mode 100644
index 0000000..b8e96ab
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_errno.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Global header for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MFC_ERRNO_H
+#define __MFC_ERRNO_H __FILE__
+
+enum mfc_ret_code {
+ MFC_OK = 1,
+ MFC_FAIL = -1000,
+ MFC_OPEN_FAIL = -1001,
+ MFC_CLOSE_FAIL = -1002,
+
+ MFC_DEC_INIT_FAIL = -2000,
+ MFC_DEC_EXE_TIME_OUT = -2001,
+ MFC_DEC_EXE_ERR = -2002,
+ MFC_DEC_GET_INBUF_FAIL = 2003,
+ MFC_DEC_SET_INBUF_FAIL = 2004,
+ MFC_DEC_GET_OUTBUF_FAIL = -2005,
+ MFC_DEC_GET_CONF_FAIL = -2006,
+ MFC_DEC_SET_CONF_FAIL = -2007,
+
+ MFC_ENC_INIT_FAIL = -3000,
+ MFC_ENC_EXE_TIME_OUT = -3001,
+ MFC_ENC_EXE_ERR = -3002,
+ MFC_ENC_GET_INBUF_FAIL = -3003,
+ MFC_ENC_SET_INBUF_FAIL = -3004,
+ MFC_ENC_GET_OUTBUF_FAIL = -3005,
+ MFC_ENC_SET_OUTBUF_FAIL = -3006,
+ MFC_ENC_GET_CONF_FAIL = -3007,
+ MFC_ENC_SET_CONF_FAIL = -3008,
+
+ MFC_STATE_INVALID = -4000,
+ MFC_DEC_HEADER_FAIL = -4001,
+ MFC_DEC_INIT_BUF_FAIL = -4002,
+ MFC_ENC_HEADER_FAIL = -5000,
+ MFC_ENC_PARAM_FAIL = -5001,
+ MFC_FRM_BUF_SIZE_FAIL = -6000,
+ MFC_FW_LOAD_FAIL = -6001,
+ MFC_FW_INIT_FAIL = -6002,
+ MFC_INST_NUM_EXCEEDED_FAIL = -6003,
+ MFC_MEM_ALLOC_FAIL = -6004,
+ MFC_MEM_INVALID_ADDR_FAIL = -6005,
+ MFC_MEM_MAPPING_FAIL = -6006,
+ MFC_GET_CONF_FAIL = -6007,
+ MFC_SET_CONF_FAIL = -6008,
+ MFC_INVALID_PARAM_FAIL = -6009,
+ MFC_API_FAIL = -9000,
+
+ MFC_CMD_FAIL = -1003,
+ MFC_SLEEP_FAIL = -1010,
+ MFC_WAKEUP_FAIL = -1020,
+
+ MFC_CLK_ON_FAIL = -1030,
+ MFC_CLK_OFF_FAIL = -1030,
+ MFC_PWR_ON_FAIL = -1040,
+ MFC_PWR_OFF_FAIL = -1041,
+};
+
+#endif /* __MFC_ERRNO_H */
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h
new file mode 100644
index 0000000..9bcee9d
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/mfc_v4l2/include/mfc_interface.h
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Global header for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MFC_INTERFACE_H
+#define __MFC_INTERFACE_H
+
+#include "mfc_errno.h"
+#include "SsbSipMfcApi.h"
+
+#define IOCTL_MFC_DEC_INIT (0x00800001)
+#define IOCTL_MFC_ENC_INIT (0x00800002)
+#define IOCTL_MFC_DEC_EXE (0x00800003)
+#define IOCTL_MFC_ENC_EXE (0x00800004)
+
+#define IOCTL_MFC_GET_IN_BUF (0x00800010)
+#define IOCTL_MFC_FREE_BUF (0x00800011)
+#define IOCTL_MFC_GET_REAL_ADDR (0x00800012)
+#define IOCTL_MFC_GET_MMAP_SIZE (0x00800014)
+#define IOCTL_MFC_SET_IN_BUF (0x00800018)
+
+#define IOCTL_MFC_SET_CONFIG (0x00800101)
+#define IOCTL_MFC_GET_CONFIG (0x00800102)
+
+#define IOCTL_MFC_SET_BUF_CACHE (0x00800201)
+
+/* MFC H/W support maximum 32 extra DPB. */
+#define MFC_MAX_EXTRA_DPB 5
+#define MFC_MAX_DISP_DELAY 0xF
+
+#define MFC_LIB_VER_MAJOR 1
+#define MFC_LIB_VER_MINOR 00
+
+#define BUF_L_UNIT (1024)
+#define Align(x, alignbyte) (((x)+(alignbyte)-1)/(alignbyte)*(alignbyte))
+
+#define MFC_ENC_NUM_SRC_BUFS 2 /* Number of source buffers to request */
+#define MFC_ENC_MAX_DST_BUFS 2 /* The maximum number of buffers */
+#define MFC_ENC_NUM_PLANES 2 /* Number of planes used by MFC Input */
+
+#define MFC_DEC_NUM_SRC_BUFS 2 /* Number of source buffers to request */
+#define MFC_DEC_MAX_DST_BUFS 32 /* The maximum number of buffers */
+#define MFC_DEC_NUM_PLANES 2 /* Number of planes used by MFC output */
+
+enum inst_type {
+ DECODER = 0x1,
+ ENCODER = 0x2,
+};
+
+enum mfc_check_state {
+ MFCSTATE_PROCESSING = 0,
+ MFCSTATE_DEC_RES_DETECT,
+ MFCSTATE_DEC_TERMINATING,
+ MFCSTATE_ENC_NO_OUTPUT,
+};
+
+typedef enum {
+ MFC_UNPACKED_PB = 0,
+ MFC_PACKED_PB = 1
+} mfc_packed_mode;
+
+typedef enum {
+ SSBSIP_MFC_LAST_FRAME_NOT_RECEIVED = 0,
+ SSBSIP_MFC_LAST_FRAME_RECEIVED = 1,
+ SSBSIP_MFC_LAST_FRAME_PROCESSED = 2
+} SSBSIP_MFC_LAST_FRAME_STATUS;
+
+typedef enum {
+ MFC_USE_NONE = 0x0000,
+ MFC_USE_YUV_BUFF = 0x0001,
+ MFC_USE_STRM_BUFF = 0x0010,
+ MFC_USE_SRC_STREAMON = 0x0100,
+ MFC_USE_DST_STREAMON = 0x1000,
+} s3c_mfc_interbuff_status;
+
+typedef struct {
+ int luma0; /* per frame (or top field) */
+ int chroma0; /* per frame (or top field) */
+ int luma1; /* per frame (or bottom field) */
+ int chroma1; /* per frame (or bottom field) */
+} SSBSIP_MFC_CRC_DATA;
+
+#ifdef S3D_SUPPORT
+struct mfc_frame_pack_sei_info {
+ int sei_avail;
+ unsigned int arrgment_id;
+ int sei_info;
+ int grid_pos;
+};
+#endif
+
+struct mfc_strm_ref_buf_arg {
+ unsigned int strm_ref_y;
+ unsigned int mv_ref_yc;
+};
+
+struct mfc_frame_buf_arg {
+ unsigned int luma;
+ unsigned int chroma;
+};
+
+struct mfc_enc_init_common_arg {
+ SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
+
+ int in_width; /* [IN] width of YUV420 frame to be encoded */
+ int in_height; /* [IN] height of YUV420 frame to be encoded */
+
+ int in_gop_num; /* [IN] GOP Number (interval of I-frame) */
+ int in_vop_quant; /* [IN] VOP quant */
+ int in_vop_quant_p; /* [IN] VOP quant for P frame */
+
+ /* [IN] RC enable */
+ /* [IN] RC enable (0:disable, 1:frame level RC) */
+ int in_rc_fr_en;
+ int in_rc_bitrate; /* [IN] RC parameter (bitrate in kbps) */
+
+ int in_rc_qbound_min; /* [IN] RC parameter (Q bound Min) */
+ int in_rc_qbound_max; /* [IN] RC parameter (Q bound Max) */
+ int in_rc_rpara; /* [IN] RC parameter (Reaction Coefficient) */
+
+ /* [IN] Multi-slice mode (0:single, 1:multiple) */
+ int in_ms_mode;
+ /* [IN] Multi-slice size (in num. of mb or byte) */
+ int in_ms_arg;
+
+ int in_mb_refresh; /* [IN] Macroblock refresh */
+
+ /* [IN] Enable (1) / Disable (0) padding with the specified values */
+ int in_pad_ctrl_on;
+
+ /* [IN] pad value if pad_ctrl_on is Enable */
+ int in_y_pad_val;
+ int in_cb_pad_val;
+ int in_cr_pad_val;
+
+ /* linear or tiled */
+ int in_frame_map;
+
+ unsigned int in_pixelcache;
+
+ unsigned int in_mapped_addr;
+ struct mfc_strm_ref_buf_arg out_u_addr;
+ struct mfc_strm_ref_buf_arg out_p_addr;
+ struct mfc_strm_ref_buf_arg out_buf_size;
+ unsigned int out_header_size;
+};
+
+struct mfc_enc_init_h263_arg {
+ int in_rc_framerate; /* [IN] RC parameter (framerate) */
+};
+
+struct mfc_enc_init_mpeg4_arg {
+ int in_profile; /* [IN] profile */
+ int in_level; /* [IN] level */
+
+ int in_vop_quant_b; /* [IN] VOP quant for B frame */
+
+ /* [IN] B frame number */
+ int in_bframenum;
+
+ /* [IN] Quarter-pel MC enable (1:enabled, 0:disabled) */
+ int in_quart_pixel;
+
+ int in_TimeIncreamentRes; /* [IN] VOP time resolution */
+ int in_VopTimeIncreament; /* [IN] Frame delta */
+};
+
+struct mfc_enc_init_h264_arg {
+ int in_profile; /* [IN] profile */
+ int in_level; /* [IN] level */
+
+ int in_vop_quant_b; /* [IN] VOP quant for B frame */
+
+ /* [IN] B frame number */
+ int in_bframenum;
+
+ /* [IN] interlace mode(0:progressive, 1:interlace) */
+ int in_interlace_mode;
+
+ /* [IN] reference number */
+ int in_reference_num;
+ /* [IN] reference number of P frame */
+ int in_ref_num_p;
+
+ int in_rc_framerate; /* [IN] RC parameter (framerate) */
+ int in_rc_mb_en; /* [IN] RC enable (0:disable, 1:MB level RC) */
+ /* [IN] MB level rate control dark region adaptive feature */
+ int in_rc_mb_dark_dis; /* (0:enable, 1:disable) */
+ /* [IN] MB level rate control smooth region adaptive feature */
+ int in_rc_mb_smooth_dis; /* (0:enable, 1:disable) */
+ /* [IN] MB level rate control static region adaptive feature */
+ int in_rc_mb_static_dis; /* (0:enable, 1:disable) */
+ /* [IN] MB level rate control activity region adaptive feature */
+ int in_rc_mb_activity_dis; /* (0:enable, 1:disable) */
+
+ /* [IN] disable deblocking filter idc */
+ int in_deblock_dis; /* (0: enable,1: disable, 2:Disable at slice boundary) */
+ /* [IN] slice alpha c0 offset of deblocking filter */
+ int in_deblock_alpha_c0;
+ /* [IN] slice beta offset of deblocking filter */
+ int in_deblock_beta;
+
+ /* [IN] ( 0 : CAVLC, 1 : CABAC ) */
+ int in_symbolmode;
+ /* [IN] (0: only 4x4 transform, 1: allow using 8x8 transform) */
+ int in_transform8x8_mode;
+
+ /* [IN] Inter weighted parameter for mode decision */
+ int in_md_interweight_pps;
+ /* [IN] Intra weighted parameter for mode decision */
+ int in_md_intraweight_pps;
+};
+
+struct mfc_enc_init_arg {
+ struct mfc_enc_init_common_arg cmn;
+ union {
+ struct mfc_enc_init_h264_arg h264;
+ struct mfc_enc_init_mpeg4_arg mpeg4;
+ struct mfc_enc_init_h263_arg h263;
+ } codec;
+};
+
+struct mfc_enc_exe_arg {
+ SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
+ unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */
+ unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */
+ unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */
+ unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */
+ unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */
+ unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */
+ unsigned int in_frametag; /* [IN] unique frame ID */
+
+ unsigned int out_frame_type; /* [OUT] frame type */
+ int out_encoded_size; /* [OUT] Length of Encoded video stream */
+ unsigned int out_Y_addr; /*[OUT]Out-buffer addr of encoded Y component */
+ unsigned int out_CbCr_addr; /*[OUT]Out-buffer addr of encoded CbCr component */
+ unsigned int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */
+ unsigned int out_frametag_bottom;/* [OUT] unique frame ID of bottom field */
+
+#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
+ unsigned int out_y_secure_id;
+ unsigned int out_c_secure_id;
+#elif defined(CONFIG_S5P_VMEM)
+ unsigned int out_y_cookie;
+ unsigned int out_c_cookie;
+#endif
+};
+
+struct mfc_dec_init_arg {
+ SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
+ int in_strm_buf; /* [IN] address of stream buffer */
+ int in_strm_size; /* [IN] filled size in stream buffer */
+ int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */
+
+ unsigned int in_crc; /* [IN] */
+ unsigned int in_pixelcache; /* [IN] */
+ unsigned int in_slice; /* [IN] */
+ unsigned int in_numextradpb; /* [IN] */
+
+ unsigned int in_mapped_addr;
+
+ int out_frm_width; /* [OUT] width of YUV420 frame */
+ int out_frm_height; /* [OUT] height of YUV420 frame */
+ int out_buf_width; /* [OUT] width of YUV420 frame */
+ int out_buf_height; /* [OUT] height of YUV420 frame */
+
+ int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding. */
+
+ int out_crop_right_offset; /* [OUT] crop information for h264 */
+ int out_crop_left_offset;
+ int out_crop_bottom_offset;
+ int out_crop_top_offset;
+};
+
+struct mfc_dec_exe_arg {
+ SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */
+ int in_strm_buf; /* [IN] the physical address of STRM_BUF */
+ /* [IN] Size of video stream filled in STRM_BUF */
+ int in_strm_size;
+ /* [IN] the address of dpb FRAME_BUF */
+ struct mfc_frame_buf_arg in_frm_buf;
+ /* [IN] size of dpb FRAME_BUF */
+ struct mfc_frame_buf_arg in_frm_size;
+ /* [IN] Unique frame ID eg. application specific timestamp */
+ unsigned int in_frametag;
+ /* [IN] immdiate Display for seek,thumbnail and one frame */
+ int in_immediately_disp;
+ /* [OUT] the physical address of display buf */
+ int out_display_Y_addr;
+ /* [OUT] the physical address of display buf */
+ int out_display_C_addr;
+ int out_display_status;
+ /* [OUT] unique frame ID of an output frame or top field */
+ unsigned int out_frametag_top;
+ /* [OUT] unique frame ID of bottom field */
+ unsigned int out_frametag_bottom;
+ int out_pic_time_top;
+ int out_pic_time_bottom;
+ int out_consumed_byte;
+
+ int out_crop_right_offset;
+ int out_crop_left_offset;
+ int out_crop_bottom_offset;
+ int out_crop_top_offset;
+
+ /* in new driver, each buffer offset must be return to the user */
+ int out_y_offset;
+ int out_c_offset;
+
+#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
+ unsigned int out_y_secure_id;
+ unsigned int out_c_secure_id;
+#elif defined(CONFIG_S5P_VMEM)
+ unsigned int out_y_cookie;
+ unsigned int out_c_cookie;
+#endif
+ int out_img_width; /* [OUT] width of YUV420 frame */
+ int out_img_height; /* [OUT] height of YUV420 frame */
+ int out_buf_width; /* [OUT] width of YUV420 frame */
+ int out_buf_height; /* [OUT] height of YUV420 frame */
+
+ int out_disp_pic_frame_type; /* [OUT] display picture frame type information */
+};
+
+struct mfc_get_config_arg {
+ /* [IN] Configurable parameter type */
+ int in_config_param;
+
+ /* [IN] Values to get for the configurable parameter. */
+ /* Maximum four integer values can be obtained; */
+ int out_config_value[4];
+};
+
+struct mfc_set_config_arg {
+ /* [IN] Configurable parameter type */
+ int in_config_param;
+
+ /* [IN] Values to be set for the configurable parameter. */
+ /* Maximum four integer values can be set. */
+ int in_config_value[4];
+};
+
+struct mfc_get_real_addr_arg {
+ unsigned int key;
+ unsigned int addr;
+};
+
+struct mfc_buf_alloc_arg {
+ enum inst_type type;
+ int size;
+ /*
+ unsigned int mapped;
+ */
+ unsigned int align;
+
+ unsigned int addr;
+ /*
+ unsigned int phys;
+ */
+#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
+ /* FIMXE: invalid secure id == -1 */
+ unsigned int secure_id;
+#elif defined(CONFIG_S5P_VMEM)
+ unsigned int cookie;
+#else
+ unsigned int offset;
+#endif
+};
+
+struct mfc_buf_free_arg {
+ unsigned int addr;
+};
+
+/* RMVME */
+struct mfc_mem_alloc_arg {
+ enum inst_type type;
+ int buff_size;
+ SSBIP_MFC_BUFFER_TYPE buf_cache_type;
+ unsigned int mapped_addr;
+#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
+ unsigned int secure_id;
+#elif defined(CONFIG_S5P_VMEM)
+ unsigned int cookie;
+#else
+ unsigned int offset;
+#endif
+};
+
+struct mfc_mem_free_arg {
+ unsigned int key;
+};
+/* RMVME */
+
+union mfc_args {
+ /*
+ struct mfc_enc_init_arg enc_init;
+
+ struct mfc_enc_init_mpeg4_arg enc_init_mpeg4;
+ struct mfc_enc_init_mpeg4_arg enc_init_h263;
+ struct mfc_enc_init_h264_arg enc_init_h264;
+ */
+ struct mfc_enc_init_arg enc_init;
+ struct mfc_enc_exe_arg enc_exe;
+
+ struct mfc_dec_init_arg dec_init;
+ struct mfc_dec_exe_arg dec_exe;
+
+ struct mfc_get_config_arg get_config;
+ struct mfc_set_config_arg set_config;
+
+ struct mfc_buf_alloc_arg buf_alloc;
+ struct mfc_buf_free_arg buf_free;
+ struct mfc_get_real_addr_arg real_addr;
+
+ /* RMVME */
+ struct mfc_mem_alloc_arg mem_alloc;
+ struct mfc_mem_free_arg mem_free;
+ /* RMVME */
+};
+
+struct mfc_common_args {
+ enum mfc_ret_code ret_code; /* [OUT] error code */
+ union mfc_args args;
+};
+
+struct mfc_enc_vui_info {
+ int aspect_ratio_idc;
+};
+
+struct mfc_dec_fimv1_info {
+ int width;
+ int height;
+};
+
+struct mfc_enc_hier_p_qp {
+ int t0_frame_qp;
+ int t2_frame_qp;
+ int t3_frame_qp;
+};
+
+#ifdef S3D_SUPPORT
+struct mfc_enc_sei_info {
+ int sei_gen_enable;
+ int curr_frame_frm0_flag;
+ int frame_pack_arrgment_type;
+};
+#endif
+
+struct mfc_enc_fmo {
+ unsigned int slice_map_type;
+ unsigned int slice_num_grp;
+ unsigned int run_length[4];
+ unsigned int sg_dir;
+ unsigned int sg_rate;
+};
+
+enum BUF_STATUS {
+ BUF_ENQUEUED,
+ BUF_DEQUEUED
+};
+
+struct mfc_dec_v4l2 {
+ char *mfc_src_bufs[MFC_DEC_NUM_SRC_BUFS]; /* information of source buffers */
+ char *mfc_dst_bufs[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* information of destination buffers */
+ char *mfc_dst_phys[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES]; /* cma information of destination buffers */
+
+ unsigned int mfc_src_bufs_len; /* needed for munmap */
+ unsigned int mfc_dst_bufs_len[MFC_DEC_NUM_PLANES]; /* needed for munmap */
+
+ unsigned int mfc_num_src_bufs; /* the number of source buffers */
+ unsigned int mfc_num_dst_bufs; /* the number of destination buffers */
+
+ char mfc_src_buf_flags[MFC_DEC_NUM_SRC_BUFS];
+ int bBeingFinalized;
+ int allocIndex;
+ int beingUsedIndex;
+};
+
+struct mfc_enc_v4l2 {
+ char *mfc_src_bufs[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES];
+ char *mfc_src_phys[MFC_ENC_NUM_SRC_BUFS][MFC_ENC_NUM_PLANES];
+ char *mfc_dst_bufs[MFC_ENC_MAX_DST_BUFS];
+
+ unsigned int mfc_src_bufs_len[MFC_ENC_NUM_PLANES];
+ unsigned int mfc_dst_bufs_len;
+
+ unsigned int mfc_num_src_bufs;
+ unsigned int mfc_num_dst_bufs;
+
+ unsigned int mfc_dst_bufs_bytes_used_len;
+ char mfc_src_buf_flags[MFC_ENC_NUM_SRC_BUFS];
+ int bRunning;
+ int bInputPhyVir; /* Flag to use MFC src as physical or virtual 0: virtual 1: physical */
+ int beingUsedIndex;
+};
+
+typedef struct {
+ int magic;
+ int hMFC;
+ int hVMEM;
+ int width;
+ int height;
+ int sizeStrmBuf;
+ struct mfc_frame_buf_arg sizeFrmBuf;
+ int displayStatus;
+ int inter_buff_status;
+ unsigned int virFreeStrmAddr;
+ unsigned int phyStrmBuf;
+ unsigned int virStrmBuf;
+ unsigned int virMvRefYC;
+ struct mfc_frame_buf_arg phyFrmBuf;
+ struct mfc_frame_buf_arg virFrmBuf;
+ unsigned int mapped_addr;
+ unsigned int mapped_size;
+ struct mfc_common_args MfcArg;
+ SSBSIP_MFC_CODEC_TYPE codecType;
+ SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo;
+ unsigned int inframetag;
+ unsigned int outframetagtop;
+ unsigned int outframetagbottom;
+ unsigned int immediatelydisp;
+ unsigned int encodedHeaderSize;
+ int encodedDataSize;
+ unsigned int encodedframeType;
+ struct mfc_frame_buf_arg encodedphyFrmBuf;
+
+ unsigned int dec_crc;
+ unsigned int dec_pixelcache;
+ unsigned int dec_slice;
+ unsigned int dec_numextradpb;
+
+ int input_cookie;
+ int input_secure_id;
+ int input_size;
+
+ /* to support non-blocking mode */
+ unsigned int encode_cnt;
+
+ struct mfc_dec_v4l2 v4l2_dec;
+ struct mfc_enc_v4l2 v4l2_enc;
+
+ int enc_frameskip;
+ int cacheablebuffer;
+ struct mfc_dec_fimv1_info fimv1_res;
+ SSBSIP_MFC_LAST_FRAME_STATUS lastframe;
+ SSBSIP_MFC_INSTRM_MODE_TYPE framemap;
+
+ int hier_p_enable;
+ struct mfc_enc_hier_p_qp hier_qp_value;
+#ifdef S3D_SUPPORT
+ struct mfc_enc_sei_info sei_info;
+#endif
+ int fmo_enable;
+ struct mfc_enc_fmo fmo_value;
+ int aso_enable;
+ int aso_sl_order[8];
+
+
+ /*ION related*/
+ int ion_fd;
+ int dst_ion_fd[MFC_DEC_MAX_DST_BUFS][MFC_DEC_NUM_PLANES];
+} _MFCLIB;
+
+#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8))
+#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8))
+
+#define SSBSIP_MFC_FAIL (0)
+
+#endif /* __MFC_INTERFACE_H */