summaryrefslogtreecommitdiffstats
path: root/exynos4/multimedia/codecs/sec_codecs
diff options
context:
space:
mode:
Diffstat (limited to 'exynos4/multimedia/codecs/sec_codecs')
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/Android.mk1
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/Android.mk11
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/Android.mk14
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/Android.mk26
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_api.h52
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_error.h22
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_ioctl.h23
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/src/srp_api.c265
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/Android.mk13
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/SACtrl.c33
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/Android.mk23
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api.h55
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h25
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h66
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api.c381
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c331
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos5/Android.mk9
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/Android.mk26
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_api.h52
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_error.h22
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_ioctl.h23
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/src/srp_api.c265
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/Android.mk11
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/Android.mk11
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/Android.mk38
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c1165
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c865
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/SsbSipMfcApi.h420
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_errno.h79
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_interface.h526
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/Android.mk34
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c1352
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c1206
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h382
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h79
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h541
-rw-r--r--exynos4/multimedia/codecs/sec_codecs/video/exynos5/Android.mk7
-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
43 files changed, 12837 insertions, 0 deletions
diff --git a/exynos4/multimedia/codecs/sec_codecs/Android.mk b/exynos4/multimedia/codecs/sec_codecs/Android.mk
new file mode 100644
index 0000000..6571161
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/Android.mk
@@ -0,0 +1 @@
+include $(all-subdir-makefiles)
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/Android.mk
new file mode 100644
index 0000000..3bc3577
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),)
+include $(LOCAL_PATH)/exynos4/Android.mk
+endif
+
+ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),)
+include $(LOCAL_PATH)/exynos5/Android.mk
+endif
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/Android.mk
new file mode 100644
index 0000000..df938be
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_AUDIO_PATH :=$(LOCAL_PATH)
+
+ifeq ($(BOARD_USE_ALP_AUDIO), true)
+ include $(LOCAL_AUDIO_PATH)/srp/alp/Android.mk
+else
+ ifeq ($(USE_ULP_AUDIO), true)
+ include $(LOCAL_AUDIO_PATH)/srp/ulp/Android.mk
+ include $(LOCAL_AUDIO_PATH)/srp/libsa_jni/Android.mk
+ endif
+endif
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/Android.mk
new file mode 100644
index 0000000..7393f68
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/Android.mk
@@ -0,0 +1,26 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_COPY_HEADERS_TO := libsecmm
+LOCAL_COPY_HEADERS := \
+ include/srp_api.h \
+ include/srp_ioctl.h \
+ include/srp_error.h
+
+LOCAL_SRC_FILES := \
+ src/srp_api.c
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/include
+
+LOCAL_MODULE := libsrpapi
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES :=
+
+LOCAL_SHARED_LIBRARIES :=
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_api.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_api.h
new file mode 100644
index 0000000..ad65b90
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_api.h
@@ -0,0 +1,52 @@
+#ifndef __SRP_API_H__
+#define __SRP_API_H__
+
+#include "srp_ioctl.h"
+#include "srp_error.h"
+
+#define SRP_DEV_NAME "dev/srp"
+
+#define SRP_INIT_BLOCK_MODE 0
+#define SRP_INIT_NONBLOCK_MODE 1
+
+#define SRP_PENDING_STATE_RUNNING 0
+#define SRP_PENDING_STATE_PENDING 1
+
+struct srp_buf_info {
+ void *mmapped_addr;
+ void *addr;
+ unsigned int mmapped_size;
+ unsigned int size;
+ int num;
+};
+
+struct srp_dec_info {
+ unsigned int sample_rate;
+ unsigned int channels;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SRP_Create(int block_mode);
+int SRP_Init();
+int SRP_Decode(void *buff, int size_byte);
+int SRP_Send_EOS(void);
+int SRP_SetParams(int id, unsigned long val);
+int SRP_GetParams(int id, unsigned long *pval);
+int SRP_Deinit(void);
+int SRP_Terminate(void);
+int SRP_IsOpen(void);
+
+int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num);
+int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num);
+int SRP_Get_Dec_Info(struct srp_dec_info *dec_info);
+int SRP_Get_PCM(void **addr, unsigned int *size);
+int SRP_Flush(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SRP_API_H__ */
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_error.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_error.h
new file mode 100644
index 0000000..7f79452
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_error.h
@@ -0,0 +1,22 @@
+#ifndef _SRP_ERROR_H_
+#define _SRP_ERROR_H_
+
+typedef enum {
+ SRP_RETURN_OK = 0,
+
+ SRP_ERROR_OPEN_FAIL = -1000,
+ SRP_ERROR_ALREADY_OPEN = -1001,
+ SRP_ERROR_NOT_READY = -1002,
+
+ SRP_ERROR_IBUF_OVERFLOW = -2000,
+ SRP_ERROR_IBUF_INFO = -2001,
+
+ SRP_ERROR_OBUF_READ = -3000,
+ SRP_ERROR_OBUF_INFO = -3001,
+ SRP_ERROR_OBUF_MMAP = -3002,
+
+ SRP_ERROR_INVALID_SETTING = -4000,
+ SRP_ERROR_GETINFO_FAIL = -4001
+} SRP_ERRORTYPE;
+
+#endif /* _SRP_ERROR_H_ */
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_ioctl.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_ioctl.h
new file mode 100644
index 0000000..21d55df
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/include/srp_ioctl.h
@@ -0,0 +1,23 @@
+#ifndef __SRP_IOCTL_H__
+#define __SRP_IOCTL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SRP_INIT (0x10000)
+#define SRP_DEINIT (0x10001)
+#define SRP_GET_MMAP_SIZE (0x10002)
+#define SRP_FLUSH (0x20002)
+#define SRP_SEND_EOS (0x20005)
+#define SRP_GET_IBUF_INFO (0x20007)
+#define SRP_GET_OBUF_INFO (0x20008)
+#define SRP_STOP_EOS_STATE (0x30007)
+#define SRP_GET_DEC_INFO (0x30008)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SRP_IOCTL_H__ */
+
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/src/srp_api.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/src/srp_api.c
new file mode 100644
index 0000000..56125fb
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/alp/src/srp_api.c
@@ -0,0 +1,265 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "srp_api.h"
+
+#define LOG_NDEBUG 1
+#define LOG_TAG "libsrpapi"
+#include <utils/Log.h>
+
+static struct srp_buf_info ibuf_info;
+static struct srp_buf_info obuf_info;
+static struct srp_buf_info pcm_info;
+
+static int srp_dev = -1;
+static int srp_block_mode = SRP_INIT_BLOCK_MODE;
+
+int SRP_Create(int block_mode)
+{
+ if (srp_dev == -1) {
+ srp_block_mode = block_mode;
+ srp_dev = open(SRP_DEV_NAME, O_RDWR |
+ ((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0));
+ if (srp_dev > 0)
+ return srp_dev;
+ else
+ return SRP_ERROR_OPEN_FAIL;
+ }
+
+ LOGE("%s: Device is already opened", __func__);
+ return SRP_ERROR_ALREADY_OPEN;
+}
+
+int SRP_Init()
+{
+ int ret = SRP_RETURN_OK;
+ unsigned int mmapped_size = 0;
+
+ if (srp_dev != -1) {
+ ret = ioctl(srp_dev, SRP_INIT);
+ if (ret < 0)
+ return ret;
+
+ /* mmap for OBUF */
+ ret = ioctl(srp_dev, SRP_GET_MMAP_SIZE, &mmapped_size);
+ if (ret < 0) {
+ LOGE("%s: SRP_GET_MMAP_SIZE is failed", __func__);
+ return SRP_ERROR_OBUF_MMAP;
+ }
+ obuf_info.mmapped_addr = mmap(0, mmapped_size,
+ PROT_READ | PROT_WRITE, MAP_SHARED, srp_dev, 0);
+ if (!obuf_info.mmapped_addr) {
+ LOGE("%s: mmap is failed", __func__);
+ return SRP_ERROR_OBUF_MMAP;
+ }
+ obuf_info.mmapped_size = mmapped_size;
+
+ ret = SRP_RETURN_OK;
+ } else {
+ LOGE("%s: Device is not ready", __func__);
+ ret = SRP_ERROR_NOT_READY; /* device is not created */
+ }
+
+ return ret;
+}
+
+int SRP_Decode(void *buff, int size_byte)
+{
+ int ret = SRP_RETURN_OK;
+
+ if (srp_dev != -1) {
+ if (size_byte > 0) {
+ LOGV("%s: Send data to RP (%d bytes)", __func__, size_byte);
+
+ ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */
+ if (ret < 0) {
+ if (ret != SRP_ERROR_IBUF_OVERFLOW)
+ LOGE("SRP_Decode returned error code: %d", ret);
+ }
+ return ret; /* Write Success */
+ } else {
+ return ret;
+ }
+ }
+
+ LOGE("%s: Device is not ready", __func__);
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_Send_EOS(void)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, SRP_SEND_EOS);
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_SetParams(int id, unsigned long val)
+{
+ if (srp_dev != -1)
+ return 0; /* not yet */
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_GetParams(int id, unsigned long *pval)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, id, pval);
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_Flush(void)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, SRP_FLUSH);
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_Get_PCM(void **addr, unsigned int *size)
+{
+ int ret = SRP_RETURN_OK;
+
+ if (srp_dev != -1) {
+ ret = read(srp_dev, &pcm_info, 0);
+ if (ret == -1) {
+ *size = 0;
+ LOGE("%s: PCM read fail", __func__);
+ return SRP_ERROR_OBUF_READ;
+ }
+
+ *addr = pcm_info.addr;
+ *size = pcm_info.size;
+ } else {
+ return SRP_ERROR_NOT_READY;
+ }
+
+ return ret; /* Read Success */
+}
+
+int SRP_Get_Dec_Info(struct srp_dec_info *dec_info)
+{
+ int ret;
+
+ if (srp_dev != -1) {
+ ret = ioctl(srp_dev, SRP_GET_DEC_INFO, dec_info);
+ if (ret < 0) {
+ LOGE("%s: Failed to get dec info", __func__);
+ return SRP_ERROR_GETINFO_FAIL;
+ }
+
+ LOGV("numChannels(%d), samplingRate(%d)", dec_info->channels, dec_info->sample_rate);
+
+ ret = SRP_RETURN_OK;
+ } else {
+ ret = SRP_ERROR_NOT_READY;
+ }
+
+ return ret;
+}
+
+int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num)
+{
+ int ret = SRP_RETURN_OK;
+
+ if (srp_dev != -1) {
+ ret = ioctl(srp_dev, SRP_GET_IBUF_INFO, &ibuf_info);
+ if (ret == -1) {
+ LOGE("%s: Failed to get Ibuf info", __func__);
+ return SRP_ERROR_IBUF_INFO;
+ }
+
+ *addr = ibuf_info.addr;
+ *size = ibuf_info.size;
+ *num = ibuf_info.num;
+
+ if (*num == 0) {
+ LOGE("%s: IBUF num is 0", __func__);
+ return SRP_ERROR_INVALID_SETTING;
+ }
+
+ ret = SRP_RETURN_OK;
+ } else {
+ ret = SRP_ERROR_NOT_READY;
+ }
+
+ return ret;
+}
+
+int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num)
+{
+ int ret = SRP_RETURN_OK;
+
+ if (srp_dev != -1) {
+ if (obuf_info.addr == NULL) {
+ ret = ioctl(srp_dev, SRP_GET_OBUF_INFO, &obuf_info);
+ if (ret < 0) {
+ LOGE("%s: SRP_GET_OBUF_INFO is failed", __func__);
+ return SRP_ERROR_OBUF_INFO;
+ }
+ }
+
+ *addr = obuf_info.addr;
+ *size = obuf_info.size;
+ *num = obuf_info.num;
+
+ if (*num == 0) {
+ LOGE("%s: OBUF num is 0", __func__);
+ return SRP_ERROR_INVALID_SETTING;
+ }
+
+ ret = SRP_RETURN_OK;
+ } else {
+ ret = SRP_ERROR_NOT_READY;
+ }
+
+ return ret;
+}
+
+int SRP_Deinit(void)
+{
+ if (srp_dev != -1) {
+ munmap(obuf_info.mmapped_addr, obuf_info.mmapped_size);
+ return ioctl(srp_dev, SRP_DEINIT);
+ }
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_Terminate(void)
+{
+ int ret;
+
+ if (srp_dev != -1) {
+ ret = close(srp_dev);
+
+ if (ret == 0) {
+ srp_dev = -1; /* device closed */
+ return SRP_RETURN_OK;
+ }
+ }
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_IsOpen(void)
+{
+ if (srp_dev == -1) {
+ LOGV("%s: Device is not opened", __func__);
+ return 0;
+ }
+
+ LOGV("%s: Device is opened", __func__);
+ return 1;
+}
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/Android.mk
new file mode 100644
index 0000000..8450845
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_MODULE := libsa_jni
+LOCAL_SRC_FILES := SACtrl.c
+
+LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_STATIC_LIBRARIES := libsrpapi
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/SACtrl.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/SACtrl.c
new file mode 100644
index 0000000..6b99dc3
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/libsa_jni/SACtrl.c
@@ -0,0 +1,33 @@
+#include <jni.h>
+#include <time.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "srp_api_ctrl.h"
+
+#define LOG_TAG "libsa_jni"
+#include <cutils/log.h>
+
+void Java_com_android_music_SetSACtrlJNI_set(JNIEnv * env, jobject obj, int effect_num)
+{
+ unsigned long effect_enable = effect_num ? 1 : 0;
+ unsigned int ret;
+
+ LOGD("Sound effect[%d]", effect_num);
+
+ ret = SRP_Ctrl_Enable_Effect(effect_enable);
+ if (ret < 0) {
+ LOGE("%s: Couldn't enabled effect\n", __func__);
+ return;
+ }
+
+ SRP_Ctrl_Set_Effect_Def(effect_num << 5);
+ if (ret < 0) {
+ LOGE("%s: Couldn't defined effect\n", __func__);
+ return;
+ }
+
+ return;
+}
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/Android.mk
new file mode 100644
index 0000000..5b1d397
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ src/srp_api.c \
+ src/srp_api_ctrl.c
+
+LOCAL_MODULE := libsrpapi
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES :=
+
+LOCAL_SHARED_LIBRARIES :=
+
+LOCAL_COPY_HEADERS := \
+ include/srp_api.h \
+ include/srp_api_ctrl.h \
+ include/srp_ioctl.h
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api.h
new file mode 100644
index 0000000..74598e5
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api.h
@@ -0,0 +1,55 @@
+#ifndef __SRP_API_H__
+#define __SRP_API_H__
+
+#include "srp_ioctl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SRP_Create(int block_mode);
+int SRP_Init(unsigned int ibuf_size);
+int SRP_Decode(void *buff, int size_byte);
+int SRP_Send_EOS(void);
+int SRP_Resume_EOS(void);
+int SRP_Pause(void);
+int SRP_Stop(void);
+int SRP_Flush(void);
+int SRP_SetParams(int id, unsigned long val);
+int SRP_GetParams(int id, unsigned long *pval);
+int SRP_Deinit(void);
+int SRP_Terminate(void);
+int SRP_IsOpen(void);
+
+#define SRP_DEV_NAME "dev/srp"
+
+#define SRP_INIT_BLOCK_MODE 0
+#define SRP_INIT_NONBLOCK_MODE 1
+
+#define SRP_PENDING_STATE_RUNNING 0
+#define SRP_PENDING_STATE_PENDING 1
+
+#define SRP_ERROR_LOSTSYNC 0x00101
+#define SRP_ERROR_BADLAYER 0x00102
+#define SRP_ERROR_BADBITRATE 0x00103
+#define SRP_ERROR_BADSAMPLERATE 0x00104
+#define SRP_ERROR_BADEMPHASIS 0x00105
+
+#define SRP_ERROR_BADCRC 0x00201
+#define SRP_ERROR_BADBITALLOC 0x00211
+#define SRP_ERROR_BADBADSCALEFACTOR 0x00221
+#define SRP_ERROR_BADFRAMELEN 0x00231
+#define SRP_ERROR_BADBIGVALUES 0x00232
+#define SRP_ERROR_BADBLOCKTYPE 0x00233
+#define SRP_ERROR_BADSCFSI 0x00234
+#define SRP_ERROR_BADDATAPTR 0x00235
+#define SRP_ERROR_BADPART3LEN 0x00236
+#define SRP_ERROR_BADHUFFTABLE 0x00237
+#define SRP_ERROR_BADHUFFDATA 0x00238
+#define SRP_ERROR_BADSTEREO 0x00239
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SRP_API_H__ */
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h
new file mode 100644
index 0000000..3b17acf
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_api_ctrl.h
@@ -0,0 +1,25 @@
+#ifndef __SRP_API_CTRL_H__
+#define __SRP_API_CTRL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SRP_CTRL_DEV_NAME "dev/srp_ctrl"
+
+int SRP_Ctrl_Set_Effect(int effect); /* test only */
+int SRP_Ctrl_Enable_Effect(int on);
+int SRP_Ctrl_Set_Effect_Def(unsigned long effect_def);
+int SRP_Ctrl_Set_Effect_EQ_User(unsigned long eq_user);
+int SRP_Ctrl_Set_Pcm_Dump(int on);
+int SRP_Ctrl_Get_Pcm_Dump_State(void);
+int SRP_Ctrl_Set_Gain(float value);
+int SRP_Ctrl_Get_Running_Stat(void);
+int SRP_Ctrl_Get_Open_Stat(void);
+short *SRP_Ctrl_Get_Pcm(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SRP_API_CTRL_H__ */
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h
new file mode 100644
index 0000000..a20b1ac
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/include/srp_ioctl.h
@@ -0,0 +1,66 @@
+#ifndef __SRP_IOCTL_H__
+#define __SRP_IOCTL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* constants for srp device node */
+#define SRP_INIT (0x10000)
+#define SRP_DEINIT (0x10001)
+
+#define SRP_PAUSE (0x20000)
+#define SRP_STOP (0x20001)
+#define SRP_FLUSH (0x20002)
+#define SRP_WAIT_EOS (0x20003)
+#define SRP_EFFECT (0x20004)
+#define SRP_SEND_EOS (0x20005)
+#define SRP_RESUME_EOS (0x20006)
+
+#define SRP_PENDING_STATE (0x30000)
+#define SRP_ERROR_STATE (0x30001)
+#define SRP_DECODED_FRAME_NO (0x30002)
+#define SRP_DECODED_ONE_FRAME_SIZE (0x30003)
+#define SRP_DECODED_FRAME_SIZE (0x30004)
+#define SRP_DECODED_PCM_SIZE (0x30005)
+#define SRP_CHANNEL_COUNT (0x30006)
+#define SRP_STOP_EOS_STATE (0x30007)
+
+/* constants for srp_ctrl device node*/
+#define SRP_CTRL_SET_GAIN (0xFF000)
+#define SRP_CTRL_SET_EFFECT (0xFF001)
+#define SRP_CTRL_GET_PCM_1KFRAME (0xFF002)
+#define SRP_CTRL_PCM_DUMP_OP (0xFF003)
+
+#define SRP_CTRL_EFFECT_ENABLE (0xFF010)
+#define SRP_CTRL_EFFECT_DEF (0xFF011)
+#define SRP_CTRL_EFFECT_EQ_USR (0xFF012)
+#define SRP_CTRL_EFFECT_SPEAKER (0xFF013)
+
+#define SRP_CTRL_IS_RUNNING (0xFF100)
+#define SRP_CTRL_IS_OPENED (0xFF101)
+#define SRP_CTRL_GET_OP_LEVEL (0xFF102)
+#define SRP_CTRL_IS_PCM_DUMP (0xFF103)
+
+#define SRP_CTRL_ALTFW_STATE (0xFF200)
+#define SRP_CTRL_ALTFW_LOAD (0xFF201)
+
+/* constants for SRP firmware */
+#define SRP_FW_CODE1 0
+#define SRP_FW_CODE20 1
+#define SRP_FW_CODE21 2
+#define SRP_FW_CODE22 3
+#define SRP_FW_CODE30 4
+#define SRP_FW_CODE31 5
+
+#define SRP_FW_VLIW 0
+#define SRP_FW_CGA 1
+#define SRP_FW_CGA_SA 2
+#define SRP_FW_DATA 3
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SRP_IOCTL_H__ */
+
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api.c
new file mode 100644
index 0000000..b0c0e5e
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api.c
@@ -0,0 +1,381 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "srp_api.h"
+
+#define LOG_TAG "libsrpapi"
+#include <cutils/log.h>
+
+/* Disable LOGD message */
+#ifdef LOGD
+#undef LOGD
+#endif
+#define LOGD(...)
+
+//#define _USE_WBUF_ /* Buffering before writing srp-rp device */
+//#define _DUMP_TO_FILE_
+//#define _USE_FW_FROM_DISK_
+
+#ifdef _USE_WBUF_
+#define WBUF_LEN_MUL 2
+#endif
+
+static int srp_dev = -1;
+static int srp_ibuf_size = 0;
+static int srp_block_mode = SRP_INIT_BLOCK_MODE;
+
+static unsigned char *wbuf;
+static int wbuf_size;
+static int wbuf_pos;
+
+#ifdef _DUMP_TO_FILE_
+static FILE *fp_dump = NULL;
+#endif
+
+#ifdef _USE_WBUF_
+static int WriteBuff_Init(void)
+{
+ if (wbuf == NULL) {
+ wbuf_size = srp_ibuf_size * WBUF_LEN_MUL;
+ wbuf_pos = 0;
+ wbuf = (unsigned char *)malloc(wbuf_size);
+ LOGD("%s: WriteBuffer %dbytes allocated", __func__, wbuf_size);
+ return 0;
+ }
+
+ LOGE("%s: WriteBuffer already allocated", __func__);
+ return -1;
+}
+
+static int WriteBuff_Deinit(void)
+{
+ if (wbuf != NULL) {
+ free(wbuf);
+ wbuf = NULL;
+ return 0;
+ }
+
+ LOGE("%s: WriteBuffer is not ready", __func__);
+ return -1;
+}
+
+static int WriteBuff_Write(unsigned char *buff, int size_byte)
+{
+ int write_byte;
+
+ if ((wbuf_pos + size_byte) < wbuf_size) {
+ memcpy(&wbuf[wbuf_pos], buff, size_byte);
+ wbuf_pos += size_byte;
+ } else {
+ LOGE("%s: WriteBuffer is filled [%d], ignoring write [%d]", __func__, wbuf_pos, size_byte);
+ return -1; /* Insufficient buffer */
+ }
+
+ return wbuf_pos;
+}
+
+static void WriteBuff_Consume(void)
+{
+ memcpy(wbuf, &wbuf[srp_ibuf_size], srp_ibuf_size * (WBUF_LEN_MUL - 1));
+ wbuf_pos -= srp_ibuf_size;
+}
+
+static void WriteBuff_Flush(void)
+{
+ wbuf_pos = 0;
+}
+#endif
+
+int SRP_Create(int block_mode)
+{
+ if (srp_dev == -1) {
+#ifdef _USE_FW_FROM_DISK_
+ SRP_Check_AltFirmware();
+#endif
+
+ srp_block_mode = block_mode;
+ srp_dev = open(SRP_DEV_NAME, O_RDWR |
+ ((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0));
+
+ return srp_dev;
+ }
+
+ LOGE("%s: Device is not ready", __func__);
+ return -1; /* device alreay opened */
+}
+
+int SRP_Init(unsigned int ibuf_size)
+{
+ int ret;
+
+ if (srp_dev != -1) {
+ srp_ibuf_size = ibuf_size;
+ ret = ioctl(srp_dev, SRP_INIT, srp_ibuf_size); /* Initialize IBUF size (4KB ~ 18KB) */
+
+#ifdef _DUMP_TO_FILE_
+ char outname[256];
+ int cnt = 0;
+
+ while (1) {
+ sprintf(outname, "/data/rp_dump_%04d.mp3", cnt++);
+ if (fp_dump = fopen(outname, "rb")) { /* file exist? */
+ fclose(fp_dump);
+ } else {
+ break;
+ }
+ }
+
+ LOGD("%s: Dump MP3 to %s", __func__, outname);
+ if (fp_dump = fopen(outname, "wb"))
+ LOGD("%s: Success to open %s", __func__, outname);
+ else
+ LOGD("%s: Fail to open %s", __func__, outname);
+#endif
+
+#ifdef _USE_WBUF_
+ if (ret != -1)
+ return WriteBuff_Init();
+#else
+ return ret;
+#endif
+ }
+
+ LOGE("%s: Device is not ready", __func__);
+ return -1; /* device is not created */
+}
+
+#ifdef _USE_WBUF_
+int SRP_Decode(void *buff, int size_byte)
+{
+ int ret;
+ int val;
+ int err_code = 0;
+
+ if (srp_dev != -1) {
+ /* Check wbuf before writing buff */
+ while (wbuf_pos >= srp_ibuf_size) { /* Write_Buffer filled? (IBUF Size)*/
+ LOGD("%s: Write Buffer is full, Send data to RP", __func__);
+
+ ret = write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */
+ if (ret == -1) { /* Fail? */
+ ioctl(srp_dev, SRP_ERROR_STATE, &val);
+ if (!val) { /* Write error? */
+ LOGE("%s: IBUF write fail", __func__);
+ return -1;
+ } else { /* Write OK, but RP decode error? */
+ err_code = val;
+ LOGE("%s: RP decode error [0x%05X]", __func__, err_code);
+ }
+ }
+#ifdef _DUMP_TO_FILE_
+ if (fp_dump)
+ fwrite(wbuf, srp_ibuf_size, 1, fp_dump);
+#endif
+ WriteBuff_Consume();
+ }
+
+ ret = WriteBuff_Write((unsigned char *)buff, size_byte);
+ if (ret == -1)
+ return -1; /* Buffering error */
+
+ LOGD("%s: Write Buffer remain [%d]", __func__, wbuf_pos);
+ return err_code; /* Write Success */
+ }
+
+ LOGE("%s: Device is not ready", __func__);
+ return -1; /* device is not created */
+}
+
+int SRP_Send_EOS(void)
+{
+ int ret;
+ int val;
+
+ if (srp_dev != -1) {
+ /* Check wbuf before writing buff */
+ while (wbuf_pos) { /* Write_Buffer ramain?*/
+ if (wbuf_pos < srp_ibuf_size) {
+ memset(wbuf + wbuf_pos, 0xFF, srp_ibuf_size - wbuf_pos); /* Fill dummy data */
+ wbuf_pos = srp_ibuf_size;
+ }
+
+ ret = write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */
+ if (ret == -1) { /* Fail? */
+ ret = ioctl(srp_dev, SRP_ERROR_STATE, &val);
+ if (!val) { /* Write error? */
+ LOGE("%s: IBUF write fail", __func__);
+ return -1;
+ } else { /* RP decoe error? */
+ LOGE("%s: RP decode error [0x%05X]", __func__, val);
+ return -1;
+ }
+ } else { /* Success? */
+#ifdef _DUMP_TO_FILE_
+ if (fp_dump)
+ fwrite(wbuf, srp_ibuf_size, 1, fp_dump);
+#endif
+ WriteBuff_Consume();
+ }
+ }
+
+ memset(wbuf, 0xFF, srp_ibuf_size); /* Fill dummy data */
+ write(srp_dev, wbuf, srp_ibuf_size); /* Write Buffer to RP Driver */
+
+ /* Wait until RP decoding over */
+ return ioctl(srp_dev, SRP_WAIT_EOS);
+ }
+
+ return -1; /* device is not created */
+}
+#else /* Without WBUF */
+int SRP_Decode(void *buff, int size_byte)
+{
+ int ret;
+ int val;
+ int err_code = 0;
+
+ if (srp_dev != -1) {
+ LOGD("%s: Send data to RP (%d bytes)", __func__, size_byte);
+
+ ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */
+ if (ret == -1) { /* Fail? */
+ ioctl(srp_dev, SRP_ERROR_STATE, &val);
+ if (!val) { /* Write error? */
+ LOGE("%s: IBUF write fail", __func__);
+ return -1;
+ } else { /* Write OK, but RP decode error? */
+ err_code = val;
+ LOGE("%s: RP decode error [0x%05X]", __func__, err_code);
+ }
+ }
+#ifdef _DUMP_TO_FILE_
+ if (fp_dump)
+ fwrite(buff, size_byte, 1, fp_dump);
+#endif
+
+ return err_code; /* Write Success */
+ }
+
+ LOGE("%s: Device is not ready", __func__);
+ return -1; /* device is not created */
+}
+
+int SRP_Send_EOS(void)
+{
+ /* Wait until RP decoding over */
+ if (srp_dev != -1)
+ return ioctl(srp_dev, SRP_SEND_EOS);
+
+ return -1; /* device is not created */
+}
+
+int SRP_Resume_EOS(void)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, SRP_RESUME_EOS);
+
+ return -1; /* device is not created */
+}
+#endif
+
+int SRP_Pause(void)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, SRP_PAUSE);
+
+ return -1; /* device is not created */
+}
+
+int SRP_Stop(void)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, SRP_STOP);
+
+ return -1; /* device is not created */
+}
+
+int SRP_Flush(void)
+{
+ if (srp_dev != -1) {
+ if (ioctl(srp_dev, SRP_FLUSH) != -1) {
+#ifdef _USE_WBUF_
+ WriteBuff_Flush();
+#endif
+ return 0;
+ }
+ }
+
+ return -1; /* device is not created */
+}
+
+
+int SRP_SetParams(int id, unsigned long val)
+{
+ if (srp_dev != -1)
+ return 0; /* not yet */
+
+ return -1; /* device is not created */
+}
+
+int SRP_GetParams(int id, unsigned long *pval)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, id, pval);
+
+ return -1; /* device is not created */
+}
+
+int SRP_Deinit(void)
+{
+ if (srp_dev != -1) {
+#ifdef _DUMP_TO_FILE_
+ if (fp_dump)
+ fclose(fp_dump);
+#endif
+
+#ifdef _USE_WBUF_
+ WriteBuff_Deinit();
+#endif
+ return ioctl(srp_dev, SRP_DEINIT); /* Deinialize */
+ }
+
+ LOGE("%s: Device is not ready", __func__);
+ return -1; /* device is not created */
+}
+
+int SRP_Terminate(void)
+{
+ int ret;
+
+ if (srp_dev != -1) {
+ ret = close(srp_dev);
+
+ if (ret == 0) {
+ srp_dev = -1; /* device closed */
+ return 0;
+ }
+ }
+
+ LOGE("%s: Device is not ready", __func__);
+ return -1; /* device is not created or close error*/
+}
+
+int SRP_IsOpen(void)
+{
+ if (srp_dev == -1) {
+ LOGD("%s: Device is not opened", __func__);
+ return 0;
+ }
+
+ LOGD("%s: Device is opened", __func__);
+ return 1;
+}
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c
new file mode 100644
index 0000000..bdc2310
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos4/srp/ulp/src/srp_api_ctrl.c
@@ -0,0 +1,331 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "srp_api_ctrl.h"
+#include "srp_ioctl.h"
+
+#define LOG_TAG "libsrpapi"
+#include <cutils/log.h>
+
+/* Disable LOGD message */
+#ifdef LOGD
+#undef LOGD
+#endif
+#define LOGD(...)
+
+static int srp_ctrl = -1;
+static int srp_ctrl_cnt = 0;
+static short pcm_buf[2048]; /* 4KBytes data, 1K frames (16bit stereo data) */
+
+#ifdef _USE_FW_FROM_DISK_
+static char srp_alt_fw_name_pre[6][32] = {
+ "sdcard/rp_fw/rp_fw_code1",
+ "sdcard/rp_fw/rp_fw_code20",
+ "sdcard/rp_fw/rp_fw_code21",
+ "sdcard/rp_fw/rp_fw_code22",
+ "sdcard/rp_fw/rp_fw_code30",
+ "sdcard/rp_fw/rp_fw_code31",
+};
+#endif
+
+static int SRP_Ctrl_Open(void)
+{
+ if (srp_ctrl_cnt == 0) {
+ srp_ctrl = open(SRP_CTRL_DEV_NAME, O_RDWR | O_NDELAY);
+ if (srp_ctrl < 0) {
+ LOGE("%s: Failed open device file %d", __func__, srp_ctrl);
+ return -1;
+ }
+ srp_ctrl_cnt++;
+ LOGV("%s: Device is opened[%d]: cnt %d", __func__, srp_ctrl, srp_ctrl_cnt);
+ }
+
+ return srp_ctrl;
+}
+
+static int SRP_Ctrl_Close(void)
+{
+ int ret = 0;
+
+ if (srp_ctrl_cnt == 1) {
+ ret = close(srp_ctrl);
+ if (ret < 0) {
+ LOGE("%s: Failed closen device file %d", __func__, srp_ctrl);
+ return -1;
+ }
+ srp_ctrl_cnt--;
+ LOGV("%s: Device is closed[%d]: cnt %d", __func__, srp_ctrl, srp_ctrl_cnt);
+ srp_ctrl = -1;
+ }
+
+ return ret;
+}
+
+#ifdef _USE_FW_FROM_DISK_
+/* This will check & download alternate firmware */
+static int SRP_Check_AltFirmware(void)
+{
+ unsigned long *temp_buff;
+ FILE *fp = NULL;
+
+ char alt_fw_name[128];
+ unsigned long alt_fw_set;
+ unsigned long alt_fw_loaded = 0;
+ int alt_fw_text_ok,alt_fw_data_ok;
+
+ if ((srp_ctrl = SRP_Ctrl_Open()) >= 0) {
+ ioctl(srp_ctrl, SRP_CTRL_ALTFW_STATE, &alt_fw_loaded);
+
+ if (!alt_fw_loaded) { /* Not loaded yet? */
+ LOGE("Try to download alternate RP firmware");
+ temp_buff = (unsigned long *)malloc(256*1024); /* temp buffer */
+
+ for (alt_fw_set = 0; alt_fw_set < 6; alt_fw_set++) {
+ sprintf(alt_fw_name, "%s_text.bin", srp_alt_fw_name_pre[alt_fw_set]);
+ if (fp = fopen(alt_fw_name, "rb")) {
+ LOGE("RP Alt-Firmware Loading: %s", alt_fw_name);
+ fread(temp_buff, 64*1024, 1, fp);
+ close(fp);
+ alt_fw_text_ok = 1;
+ } else {
+ alt_fw_text_ok = 0;
+ }
+
+ sprintf(alt_fw_name, "%s_data.bin", srp_alt_fw_name_pre[alt_fw_set]);
+ if (fp = fopen(alt_fw_name, "rb")) {
+ LOGE("RP Alt-Firmware Loading: %s", alt_fw_name);
+ fread(&temp_buff[64*1024/4], 96*1024, 1, fp);
+ close(fp);
+ alt_fw_data_ok = 1;
+ } else {
+ alt_fw_data_ok = 0;
+ }
+
+ if (alt_fw_text_ok && alt_fw_data_ok) {
+ temp_buff[160*1024/4] = alt_fw_set;
+ ioctl(srp_ctrl, SRP_CTRL_ALTFW_LOAD, temp_buff);
+ }
+ }
+ free(temp_buff);
+ }
+ SRP_Ctrl_Close();
+ }
+
+ return 0;
+}
+#endif
+
+int SRP_Ctrl_Set_Effect(int effect)
+{
+ int ret;
+ unsigned long effect_mode = (unsigned long)effect;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return -1;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_SET_EFFECT, effect_mode);
+
+ SRP_Ctrl_Close();
+
+ return 0;
+}
+
+int SRP_Ctrl_Enable_Effect(int on)
+{
+ int ret;
+ unsigned long effect_switch = on ? 1 : 0;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return -1;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_EFFECT_ENABLE, effect_switch);
+
+ SRP_Ctrl_Close();
+
+ return 0;
+}
+
+int SRP_Ctrl_Set_Effect_Def(unsigned long effect_def)
+{
+ int ret;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return -1;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_EFFECT_DEF, effect_def);
+
+ SRP_Ctrl_Close();
+
+ return 0;
+}
+
+int SRP_Ctrl_Set_Effect_EQ_User(unsigned long eq_user)
+{
+ int ret;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return -1;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_EFFECT_EQ_USR, eq_user);
+
+ SRP_Ctrl_Close();
+
+ return 0;
+}
+
+int SRP_Ctrl_Set_Pcm_Dump(int on)
+{
+ int ret;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return -1;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, on);
+
+ LOGV("dump_op: %d", on);
+
+ SRP_Ctrl_Close();
+
+ return 0;
+}
+
+int SRP_Ctrl_Get_Pcm_Dump_State(void)
+{
+ int ret;
+ int srp_dump_stat = 0;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return -1;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_IS_PCM_DUMP, &srp_dump_stat);
+
+ LOGV("srp_dump_stat: %d", srp_dump_stat);
+
+ SRP_Ctrl_Close();
+
+ return srp_dump_stat;
+}
+
+int SRP_Ctrl_Set_Gain(float value)
+{
+ int ret;
+ unsigned long gain = 0;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return -1;
+ }
+
+ gain = (unsigned long)((1 << 24) * value);
+ ioctl(srp_ctrl, SRP_CTRL_SET_GAIN, gain);
+
+ SRP_Ctrl_Close();
+
+ return 0;
+}
+
+int SRP_Ctrl_Get_Running_Stat(void)
+{
+ int ret;
+ int srp_running_stat = 0;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return -1;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_IS_RUNNING, &srp_running_stat);
+
+ LOGV("srp_running_stat: %d", srp_running_stat);
+
+ SRP_Ctrl_Close();
+
+ return srp_running_stat;
+}
+
+int SRP_Ctrl_Get_Open_Stat(void)
+{
+ int ret;
+ int srp_open_stat = 0;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return -1;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_IS_OPENED, &srp_open_stat);
+
+ LOGV("srp_open_stat: %d", srp_open_stat);
+
+ SRP_Ctrl_Close();
+
+ return srp_open_stat;
+}
+
+short *SRP_Ctrl_Get_Pcm(void)
+{
+ int ret;
+ int rp_is_running = 0;
+ int dump_is_on = 0;
+ int rp_is_opened = 0;
+
+ ret = SRP_Ctrl_Open();
+ if (ret < 0) {
+ LOGE("%s: SRP_Ctrl_Open error", __func__);
+ return NULL;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_IS_RUNNING, &rp_is_running);
+ if (rp_is_running) {
+ ioctl(srp_ctrl, SRP_CTRL_IS_PCM_DUMP, &dump_is_on);
+ if (dump_is_on == 0) {
+ ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, 1);
+ dump_is_on = 1;
+ }
+
+ ioctl(srp_ctrl, SRP_CTRL_GET_PCM_1KFRAME, pcm_buf);
+ return pcm_buf;
+ }
+
+ /* SRP is not running */
+ if (srp_ctrl > 0) {
+ if (dump_is_on) {
+ ioctl(srp_ctrl, SRP_CTRL_IS_OPENED, &rp_is_opened);
+ if (rp_is_opened)
+ ioctl(srp_ctrl, SRP_CTRL_PCM_DUMP_OP, 0);
+ }
+ SRP_Ctrl_Close();
+ }
+
+ return NULL;
+}
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/Android.mk
new file mode 100644
index 0000000..4b113e7
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/Android.mk
@@ -0,0 +1,9 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_AUDIO_PATH :=$(LOCAL_PATH)
+
+ifeq ($(BOARD_USE_ALP_AUDIO), true)
+ include $(LOCAL_AUDIO_PATH)/srp/alp/Android.mk
+endif
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/Android.mk b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/Android.mk
new file mode 100644
index 0000000..7393f68
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/Android.mk
@@ -0,0 +1,26 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_COPY_HEADERS_TO := libsecmm
+LOCAL_COPY_HEADERS := \
+ include/srp_api.h \
+ include/srp_ioctl.h \
+ include/srp_error.h
+
+LOCAL_SRC_FILES := \
+ src/srp_api.c
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/include
+
+LOCAL_MODULE := libsrpapi
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES :=
+
+LOCAL_SHARED_LIBRARIES :=
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_api.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_api.h
new file mode 100644
index 0000000..ad65b90
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_api.h
@@ -0,0 +1,52 @@
+#ifndef __SRP_API_H__
+#define __SRP_API_H__
+
+#include "srp_ioctl.h"
+#include "srp_error.h"
+
+#define SRP_DEV_NAME "dev/srp"
+
+#define SRP_INIT_BLOCK_MODE 0
+#define SRP_INIT_NONBLOCK_MODE 1
+
+#define SRP_PENDING_STATE_RUNNING 0
+#define SRP_PENDING_STATE_PENDING 1
+
+struct srp_buf_info {
+ void *mmapped_addr;
+ void *addr;
+ unsigned int mmapped_size;
+ unsigned int size;
+ int num;
+};
+
+struct srp_dec_info {
+ unsigned int sample_rate;
+ unsigned int channels;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SRP_Create(int block_mode);
+int SRP_Init();
+int SRP_Decode(void *buff, int size_byte);
+int SRP_Send_EOS(void);
+int SRP_SetParams(int id, unsigned long val);
+int SRP_GetParams(int id, unsigned long *pval);
+int SRP_Deinit(void);
+int SRP_Terminate(void);
+int SRP_IsOpen(void);
+
+int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num);
+int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num);
+int SRP_Get_Dec_Info(struct srp_dec_info *dec_info);
+int SRP_Get_PCM(void **addr, unsigned int *size);
+int SRP_Flush(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SRP_API_H__ */
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_error.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_error.h
new file mode 100644
index 0000000..7f79452
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_error.h
@@ -0,0 +1,22 @@
+#ifndef _SRP_ERROR_H_
+#define _SRP_ERROR_H_
+
+typedef enum {
+ SRP_RETURN_OK = 0,
+
+ SRP_ERROR_OPEN_FAIL = -1000,
+ SRP_ERROR_ALREADY_OPEN = -1001,
+ SRP_ERROR_NOT_READY = -1002,
+
+ SRP_ERROR_IBUF_OVERFLOW = -2000,
+ SRP_ERROR_IBUF_INFO = -2001,
+
+ SRP_ERROR_OBUF_READ = -3000,
+ SRP_ERROR_OBUF_INFO = -3001,
+ SRP_ERROR_OBUF_MMAP = -3002,
+
+ SRP_ERROR_INVALID_SETTING = -4000,
+ SRP_ERROR_GETINFO_FAIL = -4001
+} SRP_ERRORTYPE;
+
+#endif /* _SRP_ERROR_H_ */
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_ioctl.h b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_ioctl.h
new file mode 100644
index 0000000..21d55df
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/include/srp_ioctl.h
@@ -0,0 +1,23 @@
+#ifndef __SRP_IOCTL_H__
+#define __SRP_IOCTL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SRP_INIT (0x10000)
+#define SRP_DEINIT (0x10001)
+#define SRP_GET_MMAP_SIZE (0x10002)
+#define SRP_FLUSH (0x20002)
+#define SRP_SEND_EOS (0x20005)
+#define SRP_GET_IBUF_INFO (0x20007)
+#define SRP_GET_OBUF_INFO (0x20008)
+#define SRP_STOP_EOS_STATE (0x30007)
+#define SRP_GET_DEC_INFO (0x30008)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SRP_IOCTL_H__ */
+
diff --git a/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/src/srp_api.c b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/src/srp_api.c
new file mode 100644
index 0000000..56125fb
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/audio/exynos5/srp/alp/src/srp_api.c
@@ -0,0 +1,265 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "srp_api.h"
+
+#define LOG_NDEBUG 1
+#define LOG_TAG "libsrpapi"
+#include <utils/Log.h>
+
+static struct srp_buf_info ibuf_info;
+static struct srp_buf_info obuf_info;
+static struct srp_buf_info pcm_info;
+
+static int srp_dev = -1;
+static int srp_block_mode = SRP_INIT_BLOCK_MODE;
+
+int SRP_Create(int block_mode)
+{
+ if (srp_dev == -1) {
+ srp_block_mode = block_mode;
+ srp_dev = open(SRP_DEV_NAME, O_RDWR |
+ ((block_mode == SRP_INIT_NONBLOCK_MODE) ? O_NDELAY : 0));
+ if (srp_dev > 0)
+ return srp_dev;
+ else
+ return SRP_ERROR_OPEN_FAIL;
+ }
+
+ LOGE("%s: Device is already opened", __func__);
+ return SRP_ERROR_ALREADY_OPEN;
+}
+
+int SRP_Init()
+{
+ int ret = SRP_RETURN_OK;
+ unsigned int mmapped_size = 0;
+
+ if (srp_dev != -1) {
+ ret = ioctl(srp_dev, SRP_INIT);
+ if (ret < 0)
+ return ret;
+
+ /* mmap for OBUF */
+ ret = ioctl(srp_dev, SRP_GET_MMAP_SIZE, &mmapped_size);
+ if (ret < 0) {
+ LOGE("%s: SRP_GET_MMAP_SIZE is failed", __func__);
+ return SRP_ERROR_OBUF_MMAP;
+ }
+ obuf_info.mmapped_addr = mmap(0, mmapped_size,
+ PROT_READ | PROT_WRITE, MAP_SHARED, srp_dev, 0);
+ if (!obuf_info.mmapped_addr) {
+ LOGE("%s: mmap is failed", __func__);
+ return SRP_ERROR_OBUF_MMAP;
+ }
+ obuf_info.mmapped_size = mmapped_size;
+
+ ret = SRP_RETURN_OK;
+ } else {
+ LOGE("%s: Device is not ready", __func__);
+ ret = SRP_ERROR_NOT_READY; /* device is not created */
+ }
+
+ return ret;
+}
+
+int SRP_Decode(void *buff, int size_byte)
+{
+ int ret = SRP_RETURN_OK;
+
+ if (srp_dev != -1) {
+ if (size_byte > 0) {
+ LOGV("%s: Send data to RP (%d bytes)", __func__, size_byte);
+
+ ret = write(srp_dev, buff, size_byte); /* Write Buffer to RP Driver */
+ if (ret < 0) {
+ if (ret != SRP_ERROR_IBUF_OVERFLOW)
+ LOGE("SRP_Decode returned error code: %d", ret);
+ }
+ return ret; /* Write Success */
+ } else {
+ return ret;
+ }
+ }
+
+ LOGE("%s: Device is not ready", __func__);
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_Send_EOS(void)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, SRP_SEND_EOS);
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_SetParams(int id, unsigned long val)
+{
+ if (srp_dev != -1)
+ return 0; /* not yet */
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_GetParams(int id, unsigned long *pval)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, id, pval);
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_Flush(void)
+{
+ if (srp_dev != -1)
+ return ioctl(srp_dev, SRP_FLUSH);
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_Get_PCM(void **addr, unsigned int *size)
+{
+ int ret = SRP_RETURN_OK;
+
+ if (srp_dev != -1) {
+ ret = read(srp_dev, &pcm_info, 0);
+ if (ret == -1) {
+ *size = 0;
+ LOGE("%s: PCM read fail", __func__);
+ return SRP_ERROR_OBUF_READ;
+ }
+
+ *addr = pcm_info.addr;
+ *size = pcm_info.size;
+ } else {
+ return SRP_ERROR_NOT_READY;
+ }
+
+ return ret; /* Read Success */
+}
+
+int SRP_Get_Dec_Info(struct srp_dec_info *dec_info)
+{
+ int ret;
+
+ if (srp_dev != -1) {
+ ret = ioctl(srp_dev, SRP_GET_DEC_INFO, dec_info);
+ if (ret < 0) {
+ LOGE("%s: Failed to get dec info", __func__);
+ return SRP_ERROR_GETINFO_FAIL;
+ }
+
+ LOGV("numChannels(%d), samplingRate(%d)", dec_info->channels, dec_info->sample_rate);
+
+ ret = SRP_RETURN_OK;
+ } else {
+ ret = SRP_ERROR_NOT_READY;
+ }
+
+ return ret;
+}
+
+int SRP_Get_Ibuf_Info(void **addr, unsigned int *size, unsigned int *num)
+{
+ int ret = SRP_RETURN_OK;
+
+ if (srp_dev != -1) {
+ ret = ioctl(srp_dev, SRP_GET_IBUF_INFO, &ibuf_info);
+ if (ret == -1) {
+ LOGE("%s: Failed to get Ibuf info", __func__);
+ return SRP_ERROR_IBUF_INFO;
+ }
+
+ *addr = ibuf_info.addr;
+ *size = ibuf_info.size;
+ *num = ibuf_info.num;
+
+ if (*num == 0) {
+ LOGE("%s: IBUF num is 0", __func__);
+ return SRP_ERROR_INVALID_SETTING;
+ }
+
+ ret = SRP_RETURN_OK;
+ } else {
+ ret = SRP_ERROR_NOT_READY;
+ }
+
+ return ret;
+}
+
+int SRP_Get_Obuf_Info(void **addr, unsigned int *size, unsigned int *num)
+{
+ int ret = SRP_RETURN_OK;
+
+ if (srp_dev != -1) {
+ if (obuf_info.addr == NULL) {
+ ret = ioctl(srp_dev, SRP_GET_OBUF_INFO, &obuf_info);
+ if (ret < 0) {
+ LOGE("%s: SRP_GET_OBUF_INFO is failed", __func__);
+ return SRP_ERROR_OBUF_INFO;
+ }
+ }
+
+ *addr = obuf_info.addr;
+ *size = obuf_info.size;
+ *num = obuf_info.num;
+
+ if (*num == 0) {
+ LOGE("%s: OBUF num is 0", __func__);
+ return SRP_ERROR_INVALID_SETTING;
+ }
+
+ ret = SRP_RETURN_OK;
+ } else {
+ ret = SRP_ERROR_NOT_READY;
+ }
+
+ return ret;
+}
+
+int SRP_Deinit(void)
+{
+ if (srp_dev != -1) {
+ munmap(obuf_info.mmapped_addr, obuf_info.mmapped_size);
+ return ioctl(srp_dev, SRP_DEINIT);
+ }
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_Terminate(void)
+{
+ int ret;
+
+ if (srp_dev != -1) {
+ ret = close(srp_dev);
+
+ if (ret == 0) {
+ srp_dev = -1; /* device closed */
+ return SRP_RETURN_OK;
+ }
+ }
+
+ return SRP_ERROR_NOT_READY;
+}
+
+int SRP_IsOpen(void)
+{
+ if (srp_dev == -1) {
+ LOGV("%s: Device is not opened", __func__);
+ return 0;
+ }
+
+ LOGV("%s: Device is opened", __func__);
+ return 1;
+}
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/Android.mk
new file mode 100644
index 0000000..3bc3577
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+ifeq ($(filter-out exynos4,$(TARGET_BOARD_PLATFORM)),)
+include $(LOCAL_PATH)/exynos4/Android.mk
+endif
+
+ifeq ($(filter-out exynos5,$(TARGET_BOARD_PLATFORM)),)
+include $(LOCAL_PATH)/exynos5/Android.mk
+endif
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/Android.mk
new file mode 100644
index 0000000..1a8c419
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_VIDEO_PATH :=$(LOCAL_PATH)
+
+ifeq ($(BOARD_USE_V4L2), true)
+include $(LOCAL_VIDEO_PATH)/mfc_v4l2/Android.mk
+else
+include $(LOCAL_VIDEO_PATH)/mfc/Android.mk
+endif
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/Android.mk
new file mode 100644
index 0000000..b23f603
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/Android.mk
@@ -0,0 +1,38 @@
+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/
+
+LOCAL_MODULE := libsecmfcapi
+
+LOCAL_PRELINK_MODULE := false
+
+ifeq ($(BOARD_USES_MFC_FPS),true)
+LOCAL_CFLAGS := -DCONFIG_MFC_FPS
+#LOCAL_CFLAGS += -DCONFIG_MFC_PERF_LOG
+endif
+
+ifeq ($(BOARD_USE_S3D_SUPPORT), true)
+LOCAL_CFLAGS += -DS3D_SUPPORT
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES :=
+LOCAL_SHARED_LIBRARIES := liblog
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c
new file mode 100644
index 0000000..5cc7c88
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/dec/src/SsbSipMfcDecAPI.c
@@ -0,0 +1,1165 @@
+/*
+ * 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 "mfc_interface.h"
+#include "SsbSipMfcApi.h"
+
+#include <utils/Log.h>
+/*#define LOG_NDEBUG 0*/
+#undef LOG_TAG
+#define LOG_TAG "MFC_DEC_APP"
+
+#ifdef CONFIG_MFC_FPS
+#include <sys/time.h>
+#endif
+
+#define _MFCLIB_MAGIC_NUMBER 0x92241000
+
+#define USR_DATA_START_CODE (0x000001B2)
+#define VOP_START_CODE (0x000001B6)
+#define MP4_START_CODE (0x000001)
+
+#ifdef CONFIG_MFC_FPS
+unsigned int framecount, over30ms;
+struct timeval mDec1, mDec2, mAvg;
+#endif
+
+static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME;
+
+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("isPBPacked] VOP START Found !!.....return");
+ LOGW("isPBPacked] Non Packed PB");
+ return 0;
+ }
+ getAByte(strmBuffer, &startCode);
+ LOGV(">> StartCode = 0x%08x <<\n", startCode);
+ strmBuffer++;
+ leng_idx++;
+ }
+ LOGI("isPBPacked] User Data Found !!");
+
+ do {
+ if (*strmBuffer == 'p') {
+ /*LOGI(">> peter strmBuffer = 0x%08x <<\n", *strmBuffer);*/
+ LOGW("isPBPacked] Packed PB\n");
+ return 1;
+ }
+ getAByte(strmBuffer, &startCode);
+ strmBuffer++; leng_idx++;
+ } while ((leng_idx <= Frameleng) && ((startCode >> 8) != MP4_START_CODE));
+
+ if (leng_idx > Frameleng)
+ break;
+ }
+
+ LOGW("isPBPacked] Non Packed PB");
+
+ return 0;
+}
+
+void SsbSipMfcDecSetMFCName(char *devicename)
+{
+ mfc_dev_name = devicename;
+}
+
+void *SsbSipMfcDecOpen(void)
+{
+ int hMFCOpen;
+ unsigned int mapped_addr;
+ _MFCLIB *pCTX = NULL;
+ int mapped_size;
+ struct mfc_common_args CommonArg;
+
+ LOGI("[%s] MFC Library Ver %d.%02d\n",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR);
+#ifdef CONFIG_MFC_FPS
+ framecount = 0;
+ over30ms = 0;
+ mAvg.tv_sec = 0;
+ mAvg.tv_usec = 0;
+#endif
+ pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
+ if (pCTX == NULL) {
+ LOGE("SsbSipMfcDecOpen] malloc failed.\n");
+ return NULL;
+ }
+ memset(pCTX, 0, sizeof(_MFCLIB));
+
+ if (access(mfc_dev_name, F_OK) != 0) {
+ LOGE("SsbSipMfcDecOpen] MFC device node not exists");
+ free(pCTX);
+ return NULL;
+ }
+
+ hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY);
+ if (hMFCOpen < 0) {
+ LOGE("SsbSipMfcDecOpen] MFC Open failure");
+ free(pCTX);
+ return NULL;
+ }
+
+ mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg);
+ if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) {
+ LOGE("SsbSipMfcDecOpen] IOCTL_MFC_GET_MMAP_SIZE failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0);
+ if (!mapped_addr) {
+ LOGE("SsbSipMfcDecOpen] FIMV5.x driver address mapping failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ pCTX->magic = _MFCLIB_MAGIC_NUMBER;
+ pCTX->hMFC = hMFCOpen;
+ pCTX->mapped_addr = mapped_addr;
+ pCTX->mapped_size = mapped_size;
+ pCTX->inter_buff_status = MFC_USE_NONE;
+
+ return (void *)pCTX;
+}
+
+void *SsbSipMfcDecOpenExt(void *value)
+{
+ int hMFCOpen;
+ unsigned int mapped_addr;
+ _MFCLIB *pCTX = NULL;
+ int mapped_size;
+ int err;
+ struct mfc_common_args CommonArg;
+
+ LOGI("[%s] MFC Library Ver %d.%02d\n",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR);
+
+ pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
+ if (pCTX == NULL) {
+ LOGE("SsbSipMfcDecOpenExt] malloc failed.\n");
+ return NULL;
+ }
+ memset(pCTX, 0, sizeof(_MFCLIB));
+
+ if (access(mfc_dev_name, F_OK) != 0) {
+ LOGE("SsbSipMfcDecOpen] MFC device node not exists");
+ free(pCTX);
+ return NULL;
+ }
+
+ hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY);
+ if (hMFCOpen < 0) {
+ LOGE("SsbSipMfcDecOpenExt] MFC Open failure");
+ free(pCTX);
+ return NULL;
+ }
+
+ CommonArg.args.mem_alloc.buf_cache_type = *(SSBIP_MFC_BUFFER_TYPE *)value;
+
+ err = ioctl(hMFCOpen, IOCTL_MFC_SET_BUF_CACHE, &CommonArg);
+ if ((err < 0) || (CommonArg.ret_code != MFC_OK)) {
+ LOGE("SsbSipMfcDecOpenExt] IOCTL_MFC_SET_BUF_CACHE failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg);
+ if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) {
+ LOGE("SsbSipMfcDecOpenExt] IOCTL_MFC_GET_MMAP_SIZE failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0);
+ if (!mapped_addr) {
+ LOGE("SsbSipMfcDecOpenExt] FIMV5.x driver address mapping failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ pCTX->magic = _MFCLIB_MAGIC_NUMBER;
+ pCTX->hMFC = hMFCOpen;
+ pCTX->mapped_addr = mapped_addr;
+ pCTX->mapped_size = mapped_size;
+ pCTX->inter_buff_status = MFC_USE_NONE;
+
+ return (void *)pCTX;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit (void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng)
+{
+ int r;
+ int packedPB = 0;
+ struct mfc_common_args DecArg;
+ _MFCLIB *pCTX;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcDecInit] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *)openHandle;
+ memset(&DecArg, 0x00, sizeof(DecArg));
+
+ if ((codec_type != MPEG4_DEC) &&
+ (codec_type != H264_DEC) &&
+ (codec_type != H263_DEC) &&
+ (codec_type != MPEG1_DEC) &&
+ (codec_type != MPEG2_DEC) &&
+ (codec_type != FIMV1_DEC) &&
+ (codec_type != FIMV2_DEC) &&
+ (codec_type != FIMV3_DEC) &&
+ (codec_type != FIMV4_DEC) &&
+ (codec_type != XVID_DEC) &&
+ (codec_type != VC1RCV_DEC) &&
+ (codec_type != VC1_DEC)) {
+ LOGE("SsbSipMfcDecInit] Undefined codec type");
+ return MFC_RET_INVALID_PARAM;
+ }
+ 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);
+
+ /* init args */
+ DecArg.args.dec_init.in_codec_type = pCTX->codecType;
+ DecArg.args.dec_init.in_strm_size = Frameleng;
+ DecArg.args.dec_init.in_strm_buf = pCTX->phyStrmBuf;
+
+ DecArg.args.dec_init.in_numextradpb = pCTX->dec_numextradpb;
+ DecArg.args.dec_init.in_slice= pCTX->dec_slice;
+ DecArg.args.dec_init.in_crc = pCTX->dec_crc;
+ DecArg.args.dec_init.in_pixelcache = pCTX->dec_pixelcache;
+
+ DecArg.args.dec_init.in_packed_PB = packedPB;
+
+ /* mem alloc args */
+ DecArg.args.dec_init.in_mapped_addr = pCTX->mapped_addr;
+
+ /* get pyhs addr args */
+ /* no needs */
+
+ /* sequence start args */
+ /* no needs */
+
+ r = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_INIT, &DecArg);
+ if (DecArg.ret_code != MFC_OK) {
+ LOGE("SsbSipMfcDecInit] IOCTL_MFC_DEC_INIT failed");
+ return MFC_RET_DEC_INIT_FAIL;
+ }
+
+ pCTX->decOutInfo.img_width = DecArg.args.dec_init.out_frm_width;
+ pCTX->decOutInfo.img_height = DecArg.args.dec_init.out_frm_height;
+ pCTX->decOutInfo.buf_width = DecArg.args.dec_init.out_buf_width;
+ pCTX->decOutInfo.buf_height = DecArg.args.dec_init.out_buf_height;
+
+ pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_init.out_crop_top_offset;
+ pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_init.out_crop_bottom_offset;
+ pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_init.out_crop_left_offset;
+ pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_init.out_crop_right_offset;
+
+ /*
+ pCTX->virFrmBuf.luma = DecArg.args.dec_init.out_u_addr.luma;
+ pCTX->virFrmBuf.chroma = DecArg.args.dec_init.out_u_addr.chroma;
+
+ pCTX->phyFrmBuf.luma = DecArg.args.dec_init.out_p_addr.luma;
+ pCTX->phyFrmBuf.chroma = DecArg.args.dec_init.out_p_addr.chroma;
+ pCTX->sizeFrmBuf.luma = DecArg.args.dec_init.out_frame_buf_size.luma;
+ pCTX->sizeFrmBuf.chroma = DecArg.args.dec_init.out_frame_buf_size.chroma;
+ */
+
+ pCTX->inter_buff_status |= MFC_USE_YUV_BUFF;
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill)
+{
+ int ret;
+ int Yoffset;
+ int Coffset;
+ _MFCLIB *pCTX;
+ struct mfc_common_args DecArg;
+
+#ifdef CONFIG_MFC_FPS
+ long int diffTime, avgTime;
+#endif
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcDecExe] openHandle is NULL\n");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) {
+ LOGE("SsbSipMfcDecExe] lengthBufFill is invalid. (lengthBufFill=%d)", lengthBufFill);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+ memset(&DecArg, 0x00, sizeof(DecArg));
+
+ DecArg.args.dec_exe.in_codec_type = pCTX->codecType;
+ DecArg.args.dec_exe.in_strm_buf = pCTX->phyStrmBuf;
+ DecArg.args.dec_exe.in_strm_size = lengthBufFill;
+ DecArg.args.dec_exe.in_frm_buf.luma = pCTX->phyFrmBuf.luma;
+ DecArg.args.dec_exe.in_frm_buf.chroma = pCTX->phyFrmBuf.chroma;
+ DecArg.args.dec_exe.in_frm_size.luma = pCTX->sizeFrmBuf.luma;
+ DecArg.args.dec_exe.in_frm_size.chroma = pCTX->sizeFrmBuf.chroma;
+ DecArg.args.dec_exe.in_frametag = pCTX->inframetag;
+ DecArg.args.dec_exe.in_immediately_disp = pCTX->immediatelydisp;
+
+#ifdef CONFIG_MFC_FPS
+ gettimeofday(&mDec1, NULL);
+
+#ifdef CONFIG_MFC_PERF_LOG
+ if (framecount != 0) {
+ if (mDec2.tv_sec == mDec1.tv_sec)
+ LOGI("SsbSipMfcDecExe] Interval between IOCTL_MFC_DEC_EXE's (end to start) = %8d", (mDec1.tv_usec - mDec2.tv_usec));
+ else
+ LOGI("SsbSipMfcDecExe] Interval between IOCTL_MFC_DEC_EXE's (end to start) = %8d", (1000000 + (mDec1.tv_usec - mDec2.tv_usec)));
+ }
+#endif
+#endif
+
+ ret = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_EXE, &DecArg);
+
+ if (DecArg.ret_code != MFC_OK) {
+ LOGE("SsbSipMfcDecExe] IOCTL_MFC_DEC_EXE failed(ret : %d)", DecArg.ret_code);
+ return MFC_RET_DEC_EXE_ERR;
+ }
+
+#ifdef CONFIG_MFC_FPS
+ gettimeofday(&mDec2, NULL);
+ framecount++;
+
+ if (mDec1.tv_sec == mDec2.tv_sec) {
+ if (mDec2.tv_usec - mDec1.tv_usec > 30000)
+ over30ms++;
+#ifdef CONFIG_MFC_PERF_LOG
+ LOGI("SsbSipMfcDecExe] Time consumed for IOCTL_MFC_DEC_EXE = %8d", ((mDec2.tv_usec - mDec1.tv_usec)));
+#endif
+ } else {
+ if (1000000 + mDec2.tv_usec - mDec1.tv_usec > 30000)
+ over30ms++;
+#ifdef CONFIG_MFC_PERF_LOG
+ LOGI("SsbSipMfcDecExe] Time consumed for IOCTL_MFC_DEC_EXE = %8d", (1000000 + (mDec2.tv_usec - mDec1.tv_usec)));
+#endif
+ }
+
+ diffTime = ((mDec2.tv_sec * 1000000) + mDec2.tv_usec) - ((mDec1.tv_sec * 1000000) + mDec1.tv_usec);
+ avgTime = (mAvg.tv_sec * 1000000) + mAvg.tv_usec;
+ avgTime = ((framecount - 1) * avgTime + diffTime) / framecount;
+
+ mAvg.tv_sec = avgTime / 1000000;
+ mAvg.tv_usec = avgTime % 1000000;
+#endif
+
+ /* FIXME: dynamic resolution change */
+ if (DecArg.args.dec_exe.out_display_status == 4) {
+ LOGI("SsbSipMfcDecExe] Resolution is chagned");
+ /*
+ pCTX->virFrmBuf.chroma = DecArg.args.dec_exe.out_u_addr.chroma;
+ pCTX->virFrmBuf.luma = DecArg.args.dec_exe.out_u_addr.luma;
+ pCTX->phyFrmBuf.chroma = DecArg.args.dec_exe.out_p_addr.chroma;
+ pCTX->phyFrmBuf.luma = DecArg.args.dec_exe.out_p_addr.luma;
+ pCTX->sizeFrmBuf.chroma = DecArg.args.dec_exe.out_frame_buf_size.chroma;
+ pCTX->sizeFrmBuf.luma = DecArg.args.dec_exe.out_frame_buf_size.luma;
+ */
+ pCTX->decOutInfo.img_width = DecArg.args.dec_exe.out_img_width;
+ pCTX->decOutInfo.img_height = DecArg.args.dec_exe.out_img_height;
+ pCTX->decOutInfo.buf_width = DecArg.args.dec_exe.out_buf_width;
+ pCTX->decOutInfo.buf_height = DecArg.args.dec_exe.out_buf_height;
+ }
+
+ Yoffset = DecArg.args.dec_exe.out_display_Y_addr - DecArg.args.dec_exe.in_frm_buf.luma;
+ Coffset = DecArg.args.dec_exe.out_display_C_addr - DecArg.args.dec_exe.in_frm_buf.chroma;
+
+ pCTX->decOutInfo.YPhyAddr = (void*)(DecArg.args.dec_exe.out_display_Y_addr);
+ pCTX->decOutInfo.CPhyAddr = (void*)(DecArg.args.dec_exe.out_display_C_addr);
+
+ pCTX->decOutInfo.YVirAddr = (void*)(pCTX->virFrmBuf.luma + Yoffset);
+ pCTX->decOutInfo.CVirAddr = (void*)(pCTX->virFrmBuf.chroma + Coffset);
+
+ /* for new driver */
+ pCTX->decOutInfo.YVirAddr = (void*)(pCTX->mapped_addr + DecArg.args.dec_exe.out_y_offset);
+ pCTX->decOutInfo.CVirAddr = (void*)(pCTX->mapped_addr + DecArg.args.dec_exe.out_c_offset);
+
+ pCTX->displayStatus = DecArg.args.dec_exe.out_display_status;
+
+ pCTX->decOutInfo.disp_pic_frame_type = DecArg.args.dec_exe.out_disp_pic_frame_type;
+
+ /* clear immediately display flag */
+ pCTX->immediatelydisp = 0;
+ pCTX->outframetagtop = DecArg.args.dec_exe.out_frametag_top;
+ pCTX->outframetagbottom = DecArg.args.dec_exe.out_frametag_bottom;
+ pCTX->decOutInfo.timestamp_top = DecArg.args.dec_exe.out_pic_time_top;
+ pCTX->decOutInfo.timestamp_bottom = DecArg.args.dec_exe.out_pic_time_bottom;
+ pCTX->decOutInfo.consumedByte = DecArg.args.dec_exe.out_consumed_byte;
+
+ pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_exe.out_crop_right_offset;
+ pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_exe.out_crop_left_offset;
+ pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_exe.out_crop_bottom_offset;
+ pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_exe.out_crop_top_offset;
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle)
+{
+ int ret;
+ _MFCLIB *pCTX;
+ struct mfc_common_args free_arg;
+
+#ifdef CONFIG_MFC_FPS
+ LOGI(">>> Statistics in MFC API:");
+ LOGI(">>> Total number of IOCTL_MFC_DEC_EXE = %d", framecount);
+ LOGI(">>> Number of IOCTL_MFC_DEC_EXE taking more than 30ms = %d", over30ms);
+ LOGI(">>> Avg IOCTL_MFC_DEC_EXE time = %dsec %.2fmsec", (int)mAvg.tv_sec, (float)(mAvg.tv_usec / 1000.0));
+#endif
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcDecClose] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ /* FIXME: free buffer? */
+#if 0
+ if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) {
+ free_arg.args.mem_free.key = pCTX->virFrmBuf.luma;
+ ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
+ free_arg.args.mem_free.key = pCTX->virFrmBuf.chroma;
+ ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
+ }
+#endif
+
+ if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) {
+ free_arg.args.mem_free.key = pCTX->virStrmBuf;
+ ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
+ }
+
+ pCTX->inter_buff_status = MFC_USE_NONE;
+
+ munmap((void *)pCTX->mapped_addr, pCTX->mapped_size);
+ close(pCTX->hMFC);
+ free(pCTX);
+
+ return MFC_RET_OK;
+}
+
+
+void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize)
+{
+ int ret_code;
+ _MFCLIB *pCTX;
+ struct mfc_common_args user_addr_arg, phys_addr_arg;
+
+ if (inputBufferSize < 0) {
+ LOGE("SsbSipMfcDecGetInBuf] inputBufferSize = %d is invalid", inputBufferSize);
+ return NULL;
+ }
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcDecGetInBuf] openHandle is NULL\n");
+ return NULL;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ /*user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type; */
+ user_addr_arg.args.mem_alloc.type = DECODER;
+ user_addr_arg.args.mem_alloc.buff_size = inputBufferSize;
+ user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr;
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg);
+ if (ret_code < 0) {
+ LOGE("SsbSipMfcDecGetInBuf] IOCTL_MFC_GET_IN_BUF failed");
+ return NULL;
+ }
+
+ phys_addr_arg.args.real_addr.key = user_addr_arg.args.mem_alloc.offset;
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_REAL_ADDR, &phys_addr_arg);
+ if (ret_code < 0) {
+ LOGE("SsbSipMfcDecGetInBuf] IOCTL_MFC_GET_PHYS_ADDR failed");
+ return NULL;
+ }
+
+ /*
+ pCTX->virStrmBuf = user_addr_arg.args.mem_alloc.offset;
+ */
+ pCTX->virStrmBuf = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset;
+ pCTX->phyStrmBuf = phys_addr_arg.args.real_addr.addr;
+
+ pCTX->sizeStrmBuf = inputBufferSize;
+ pCTX->inter_buff_status |= MFC_USE_STRM_BUFF;
+
+ *phyInBuf = (void *)pCTX->phyStrmBuf;
+
+ return (void *)pCTX->virStrmBuf;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int size)
+{
+ _MFCLIB *pCTX;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcDecSetInBuf] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ pCTX->phyStrmBuf = (int)phyInBuf;
+ pCTX->virStrmBuf = (int)virInBuf;
+ pCTX->sizeStrmBuf = size;
+ 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("SsbSipMfcDecGetOutBuf] openHandle is NULL");
+ 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->timestamp_top = pCTX->decOutInfo.timestamp_top;
+ output_info->timestamp_bottom = pCTX->decOutInfo.timestamp_bottom;
+ output_info->consumedByte = pCTX->decOutInfo.consumedByte;
+
+ 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;
+
+ if (pCTX->displayStatus == 3)
+ return MFC_GETOUTBUF_DISPLAY_END;
+ else if (pCTX->displayStatus == 1)
+ return MFC_GETOUTBUF_DISPLAY_DECODING;
+ else if (pCTX->displayStatus == 2)
+ return MFC_GETOUTBUF_DISPLAY_ONLY;
+ else if (pCTX->displayStatus == 0)
+ return MFC_GETOUTBUF_DECODING_ONLY;
+ else if (pCTX->displayStatus == 4)
+ return MFC_GETOUTBUF_CHANGE_RESOL;
+ else
+ return MFC_GETOUTBUF_DISPLAY_END;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value)
+{
+ int ret_code;
+ _MFCLIB *pCTX;
+ struct mfc_common_args DecArg;
+ struct mfc_dec_fimv1_info *fimv1_res;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcDecSetConfig] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if (value == NULL) {
+ LOGE("SsbSipMfcDecSetConfig] value is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *)openHandle;
+ memset(&DecArg, 0x00, sizeof(DecArg));
+#ifdef S3D_SUPPORT
+ DecArg.args.config.type = conf_type;
+#else
+ DecArg.args.set_config.in_config_param = conf_type;
+#endif
+ switch (conf_type) {
+ case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM:
+ pCTX->dec_numextradpb = *((unsigned int *) value);
+ return MFC_RET_OK;
+
+ case MFC_DEC_SETCONF_SLICE_ENABLE:
+ pCTX->dec_slice = *((unsigned int *) value);
+ return MFC_RET_OK;
+
+ case MFC_DEC_SETCONF_CRC_ENABLE:
+ pCTX->dec_crc = *((unsigned int *) value);
+ return MFC_RET_OK;
+
+ case MFC_DEC_SETCONF_PIXEL_CACHE:
+ pCTX->dec_pixelcache = *((unsigned int *) value);
+ return MFC_RET_OK;
+
+ case MFC_DEC_SETCONF_FRAME_TAG: /* be set before calling SsbSipMfcDecExe */
+ pCTX->inframetag = *((unsigned int *) value);
+ return MFC_RET_OK;
+
+ case MFC_DEC_SETCONF_IMMEDIATELY_DISPLAY: /* be set before calling SsbSipMfcDecExe */
+ pCTX->immediatelydisp = *((unsigned int *) value);
+ return MFC_RET_OK;
+
+ case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT:
+ fimv1_res = (struct mfc_dec_fimv1_info *)value;
+ LOGI("fimv1->width = %d\n", fimv1_res->width);
+ LOGI("fimv1->height = %d\n", fimv1_res->height);
+#ifdef S3D_SUPPORT
+ DecArg.args.config.args.basic.values[0] = (int)(fimv1_res->width);
+ DecArg.args.config.args.basic.values[1] = (int)(fimv1_res->height);
+#else
+ DecArg.args.set_config.in_config_value[0] = (int)(fimv1_res->width);
+ DecArg.args.set_config.in_config_value[1] = (int)(fimv1_res->height);
+#endif
+ break;
+ case MFC_DEC_SETCONF_IS_LAST_FRAME:
+ case MFC_DEC_SETCONF_DPB_FLUSH:
+#ifdef S3D_SUPPORT
+ case MFC_DEC_SETCONF_SEI_PARSE:
+ default:
+ DecArg.args.config.args.basic.values[0] = *((int *) value);
+ DecArg.args.config.args.basic.values[1] = 0;
+#else
+ default:
+ DecArg.args.set_config.in_config_value[0] = *((unsigned int *) value);
+ DecArg.args.set_config.in_config_value[1] = 0;
+#endif
+ break;
+ }
+
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &DecArg);
+ if (DecArg.ret_code != MFC_OK) {
+ LOGE("SsbSipMfcDecSetConfig] IOCTL_MFC_SET_CONFIG failed(ret : %d, conf_type: 0x%08x)", DecArg.ret_code, 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)
+{
+ int ret_code;
+ _MFCLIB *pCTX;
+ struct mfc_common_args DecArg;
+
+ /*
+ s3c_mfc_common_args phys_addr_arg;
+ SSBSIP_MFC_BUFFER_ADDR *buf_addr;
+ */
+
+ SSBSIP_MFC_IMG_RESOLUTION *img_resolution;
+ SSBSIP_MFC_CRC_DATA *crc_data;
+ SSBSIP_MFC_CROP_INFORMATION *crop_information;
+#ifdef S3D_SUPPORT
+ SSBSIP_MFC_FRAME_PACKING *frame_packing;
+#endif
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcDecGetConfig] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if (value == NULL) {
+ LOGE("SsbSipMfcDecGetConfig] value is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ switch (conf_type) {
+#if 0
+ case MFC_DEC_GETCONF_PHYS_ADDR:
+ buf_addr = (SSBSIP_MFC_BUFFER_ADDR *)value;
+ phys_addr_arg.args.get_phys_addr.u_addr = buf_addr->u_addr;
+ r = ioctl(pCTX->hMFC, IOCTL_MFC_GET_PHYS_ADDR, &phys_addr_arg);
+ if (r < 0) {
+ LOGE("SsbSipMfcDecGetConfig] IOCTL_MFC_GET_PHYS_ADDR failed");
+ return MFC_API_FAIL;
+ }
+ buf_addr->p_addr = phys_addr_arg.args.get_phys_addr.p_addr;
+ break;
+#endif
+ 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:
+ *((unsigned int *)value) = pCTX->outframetagtop;
+ break;
+ 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;
+ case MFC_DEC_GETCONF_CRC_DATA:
+#ifdef S3D_SUPPORT
+ case MFC_DEC_GETCONF_FRAME_PACKING:
+ memset(&DecArg, 0x00, sizeof(DecArg));
+ DecArg.args.config.type = conf_type;
+
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_CONFIG, &DecArg);
+ if (DecArg.ret_code != MFC_OK) {
+ LOGE("SsbSipMfcDecGetConfig] IOCTL_MFC_GET_CONFIG failed(ret : %d, conf_type: 0x%08x)", DecArg.ret_code, conf_type);
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+
+ if (conf_type == MFC_DEC_GETCONF_CRC_DATA) {
+ crc_data = (SSBSIP_MFC_CRC_DATA *)value;
+
+ crc_data->luma0 = DecArg.args.config.args.basic.values[0];
+ crc_data->chroma0 = DecArg.args.config.args.basic.values[1];
+ } else {
+ frame_packing = (SSBSIP_MFC_FRAME_PACKING *)value;
+ memcpy(frame_packing, &DecArg.args.config.args.frame_packing,
+ sizeof(SSBSIP_MFC_FRAME_PACKING));
+ }
+#else
+ crc_data = (SSBSIP_MFC_CRC_DATA *)value;
+
+ memset(&DecArg, 0x00, sizeof(DecArg));
+ DecArg.args.get_config.in_config_param = conf_type;
+
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_CONFIG, &DecArg);
+ if (DecArg.ret_code != MFC_OK) {
+ LOGE("SsbSipMfcDecGetConfig] IOCTL_MFC_GET_CONFIG failed(ret : %d, conf_type: 0x%08x)", DecArg.ret_code, conf_type);
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+ crc_data->luma0 = DecArg.args.get_config.out_config_value[0];
+ crc_data->chroma0 = DecArg.args.get_config.out_config_value[1];
+#endif
+ break;
+ default:
+ LOGE("SsbSipMfcDecGetConfig] No such conf_type is supported");
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+
+ return MFC_RET_OK;
+}
+
+void *SsbSipMfcDecAllocInputBuffer(void *openHandle, void **phyInBuf, int inputBufferSize)
+{
+ int ret_code;
+ _MFCLIB *pCTX;
+ struct mfc_common_args user_addr_arg, phys_addr_arg;
+
+ if (inputBufferSize < 0) {
+ LOGE("SsbSipMfcDecAllocInputBuffer] inputBufferSize = %d is invalid\n", inputBufferSize);
+ return NULL;
+ }
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcDecAllocInputBuffer] openHandle is NULL\n");
+ return NULL;
+ }
+
+ pCTX = (_MFCLIB *)openHandle;
+
+ user_addr_arg.args.mem_alloc.type = DECODER;
+ user_addr_arg.args.mem_alloc.buff_size = inputBufferSize;
+ user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr;
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg);
+ if (ret_code < 0) {
+ LOGE("SsbSipMfcDecAllocInputBuffer] IOCTL_MFC_GET_IN_BUF failed");
+ return NULL;
+ }
+
+ phys_addr_arg.args.real_addr.key = user_addr_arg.args.mem_alloc.offset;
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_REAL_ADDR, &phys_addr_arg);
+ if (ret_code < 0) {
+ LOGE("SsbSipMfcDecGetInBuf] IOCTL_MFC_GET_PHYS_ADDR failed");
+ return NULL;
+ }
+
+ pCTX->virStrmBuf = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset;
+ pCTX->phyStrmBuf = phys_addr_arg.args.real_addr.addr;
+ pCTX->sizeStrmBuf = inputBufferSize;
+ pCTX->inter_buff_status |= MFC_USE_STRM_BUFF;
+
+ *phyInBuf = (void *)pCTX->phyStrmBuf;
+
+ return (void *)pCTX->virStrmBuf;
+}
+
+void SsbSipMfcDecFreeInputBuffer(void *openHandle, void *phyInBuf)
+{
+ int ret;
+ _MFCLIB *pCTX;
+ struct mfc_common_args free_arg;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcDecFreeInputBuffer] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *)openHandle;
+
+ if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) {
+ free_arg.args.mem_free.key = pCTX->virStrmBuf;
+ ret = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
+ }
+ pCTX->inter_buff_status = MFC_USE_NONE;
+ return MFC_RET_OK;
+}
+
+/* CRESPO */
+#if 1
+int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
+{
+ int pixel_x_m1, pixel_y_m1;
+ int roundup_x, roundup_y;
+ int linear_addr0, linear_addr1, bank_addr ;
+ int x_addr;
+ int trans_addr;
+
+ pixel_x_m1 = x_size -1;
+ pixel_y_m1 = y_size -1;
+
+ roundup_x = ((pixel_x_m1 >> 7) + 1);
+ roundup_y = ((pixel_x_m1 >> 6) + 1);
+
+ x_addr = x_pos >> 2;
+
+ if ((y_size <= y_pos+32) && ( y_pos < y_size) &&
+ (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
+ linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ } else {
+ linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ }
+
+ linear_addr0 = linear_addr0 << 2;
+ trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0;
+
+ return trans_addr;
+}
+
+void Y_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size)
+{
+ int trans_addr;
+ unsigned int i, j, k, index;
+ unsigned char data8[4];
+ unsigned int max_index = x_size * y_size;
+
+ for (i = 0; i < y_size; i = i + 16) {
+ for (j = 0; j < x_size; j = j + 16) {
+ trans_addr = tile_4x2_read(x_size, y_size, j, i);
+ for (k = 0; k < 16; k++) {
+ /* limit check - prohibit segmentation fault */
+ index = (i * x_size) + (x_size * k) + j;
+ /* remove equal condition to solve thumbnail bug */
+ if (index + 16 > max_index) {
+ continue;
+ }
+
+ data8[0] = p_tiled_addr[trans_addr + 64 * k + 0];
+ data8[1] = p_tiled_addr[trans_addr + 64 * k + 1];
+ data8[2] = p_tiled_addr[trans_addr + 64 * k + 2];
+ data8[3] = p_tiled_addr[trans_addr + 64 * k + 3];
+
+ p_linear_addr[index] = data8[0];
+ p_linear_addr[index + 1] = data8[1];
+ p_linear_addr[index + 2] = data8[2];
+ p_linear_addr[index + 3] = data8[3];
+
+ data8[0] = p_tiled_addr[trans_addr + 64 * k + 4];
+ data8[1] = p_tiled_addr[trans_addr + 64 * k + 5];
+ data8[2] = p_tiled_addr[trans_addr + 64 * k + 6];
+ data8[3] = p_tiled_addr[trans_addr + 64 * k + 7];
+
+ p_linear_addr[index + 4] = data8[0];
+ p_linear_addr[index + 5] = data8[1];
+ p_linear_addr[index + 6] = data8[2];
+ p_linear_addr[index + 7] = data8[3];
+
+ data8[0] = p_tiled_addr[trans_addr + 64 * k + 8];
+ data8[1] = p_tiled_addr[trans_addr + 64 * k + 9];
+ data8[2] = p_tiled_addr[trans_addr + 64 * k + 10];
+ data8[3] = p_tiled_addr[trans_addr + 64 * k + 11];
+
+ p_linear_addr[index + 8] = data8[0];
+ p_linear_addr[index + 9] = data8[1];
+ p_linear_addr[index + 10] = data8[2];
+ p_linear_addr[index + 11] = data8[3];
+
+ data8[0] = p_tiled_addr[trans_addr + 64 * k + 12];
+ data8[1] = p_tiled_addr[trans_addr + 64 * k + 13];
+ data8[2] = p_tiled_addr[trans_addr + 64 * k + 14];
+ data8[3] = p_tiled_addr[trans_addr + 64 * k + 15];
+
+ p_linear_addr[index + 12] = data8[0];
+ p_linear_addr[index + 13] = data8[1];
+ p_linear_addr[index + 14] = data8[2];
+ p_linear_addr[index + 15] = data8[3];
+ }
+ }
+ }
+}
+
+void CbCr_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size)
+{
+ int trans_addr;
+ unsigned int i, j, k, index;
+ unsigned char data8[4];
+ unsigned int half_y_size = y_size / 2;
+ unsigned int max_index = x_size * half_y_size;
+ unsigned char *pUVAddr[2];
+
+ pUVAddr[0] = p_linear_addr;
+ pUVAddr[1] = p_linear_addr + ((x_size * half_y_size) / 2);
+
+ for (i = 0; i < half_y_size; i = i + 16) {
+ for (j = 0; j < x_size; j = j + 16) {
+ trans_addr = tile_4x2_read(x_size, half_y_size, j, i);
+ for (k = 0; k < 16; k++) {
+ /* limit check - prohibit segmentation fault */
+ index = (i * x_size) + (x_size * k) + j;
+ /* remove equal condition to solve thumbnail bug */
+ if (index + 16 > max_index) {
+ continue;
+ }
+
+ data8[0] = p_tiled_addr[trans_addr + 64 * k + 0];
+ data8[1] = p_tiled_addr[trans_addr + 64 * k + 1];
+ data8[2] = p_tiled_addr[trans_addr + 64 * k + 2];
+ data8[3] = p_tiled_addr[trans_addr + 64 * k + 3];
+
+ pUVAddr[index%2][index/2] = data8[0];
+ pUVAddr[(index+1)%2][(index+1)/2] = data8[1];
+ pUVAddr[(index+2)%2][(index+2)/2] = data8[2];
+ pUVAddr[(index+3)%2][(index+3)/2] = data8[3];
+
+ data8[0] = p_tiled_addr[trans_addr + 64 * k + 4];
+ data8[1] = p_tiled_addr[trans_addr + 64 * k + 5];
+ data8[2] = p_tiled_addr[trans_addr + 64 * k + 6];
+ data8[3] = p_tiled_addr[trans_addr + 64 * k + 7];
+
+ pUVAddr[(index+4)%2][(index+4)/2] = data8[0];
+ pUVAddr[(index+5)%2][(index+5)/2] = data8[1];
+ pUVAddr[(index+6)%2][(index+6)/2] = data8[2];
+ pUVAddr[(index+7)%2][(index+7)/2] = data8[3];
+
+ data8[0] = p_tiled_addr[trans_addr + 64 * k + 8];
+ data8[1] = p_tiled_addr[trans_addr + 64 * k + 9];
+ data8[2] = p_tiled_addr[trans_addr + 64 * k + 10];
+ data8[3] = p_tiled_addr[trans_addr + 64 * k + 11];
+
+ pUVAddr[(index+8)%2][(index+8)/2] = data8[0];
+ pUVAddr[(index+9)%2][(index+9)/2] = data8[1];
+ pUVAddr[(index+10)%2][(index+10)/2] = data8[2];
+ pUVAddr[(index+11)%2][(index+11)/2] = data8[3];
+
+ data8[0] = p_tiled_addr[trans_addr + 64 * k + 12];
+ data8[1] = p_tiled_addr[trans_addr + 64 * k + 13];
+ data8[2] = p_tiled_addr[trans_addr + 64 * k + 14];
+ data8[3] = p_tiled_addr[trans_addr + 64 * k + 15];
+
+ pUVAddr[(index+12)%2][(index+12)/2] = data8[0];
+ pUVAddr[(index+13)%2][(index+13)/2] = data8[1];
+ pUVAddr[(index+14)%2][(index+14)/2] = data8[2];
+ pUVAddr[(index+15)%2][(index+15)/2] = data8[3];
+ }
+ }
+ }
+}
+#else
+int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
+{
+ int pixel_x_m1, pixel_y_m1;
+ int roundup_x, roundup_y;
+ int linear_addr0, linear_addr1, bank_addr;
+ int x_addr;
+ int trans_addr;
+
+ pixel_x_m1 = x_size -1;
+ pixel_y_m1 = y_size -1;
+
+ roundup_x = ((pixel_x_m1 >> 7) + 1);
+ roundup_y = ((pixel_x_m1 >> 6) + 1);
+
+ x_addr = x_pos >> 2;
+
+ if ((y_size <= y_pos+32) &&
+ ( y_pos < y_size) &&
+ (((pixel_y_m1 >> 5) & 0x1) == 0) &&
+ (((y_pos >> 5) & 0x1) == 0)) {
+ linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ } else {
+ linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ }
+
+ linear_addr0 = linear_addr0 << 2;
+ trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0;
+
+ return trans_addr;
+}
+
+
+void tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size)
+{
+ int trans_addr;
+ unsigned int i, j, k, nn, mm;
+ unsigned int ix,iy, nx, ny;
+
+ nx = x_size % 16;
+ ny = y_size % 16;
+
+ if (nx != 0)
+ ix = 16;
+ else
+ ix = 1;
+
+ if (ny != 0)
+ iy = 16;
+ else
+ iy = 1;
+
+ for (i = 0; i < y_size - iy; i = i + 16) {
+ for (j = 0; j < x_size -ix; j = j + 16) {
+ trans_addr = tile_4x2_read(x_size, y_size, j, i);
+
+ k = 0; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 1; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 2; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 3; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 4; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 5; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 6; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 7; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 8; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 9; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 10; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 11; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 12; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 13; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 14; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+
+ k = 15; nn = trans_addr + (k << 6); mm =x_size*(i+k) + j;
+ memcpy(p_linear_addr+mm, p_tiled_addr+nn, 16);
+ }
+ }
+}
+#endif
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c
new file mode 100644
index 0000000..4b9df6c
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/enc/src/SsbSipMfcEncAPI.c
@@ -0,0 +1,865 @@
+/*
+ * 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 <math.h>
+
+#include "mfc_interface.h"
+#include "SsbSipMfcApi.h"
+
+#include <utils/Log.h>
+/* #define LOG_NDEBUG 0 */
+#undef LOG_TAG
+#define LOG_TAG "MFC_ENC_APP"
+
+#define _MFCLIB_MAGIC_NUMBER 0x92241001
+
+static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME;
+
+void SsbSipMfcEncSetMFCName(char *devicename)
+{
+ mfc_dev_name = devicename;
+}
+
+void *SsbSipMfcEncOpen(void)
+{
+ int hMFCOpen;
+ _MFCLIB *pCTX = NULL;
+ unsigned int mapped_addr;
+ int mapped_size;
+ struct mfc_common_args CommonArg;
+
+ LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR);
+
+#if 0
+ if ((codecType != MPEG4_ENC) &&
+ (codecType != H264_ENC) &&
+ (codecType != H263_ENC)) {
+ LOGE("SsbSipMfcEncOpen] Undefined codec type");
+ return NULL;
+ }
+#endif
+
+ if (access(mfc_dev_name, F_OK) != 0) {
+ LOGE("SsbSipMfcEncOpen] MFC device node not exists");
+ return NULL;
+ }
+
+ hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY);
+ if (hMFCOpen < 0) {
+ LOGE("SsbSipMfcEncOpen] MFC Open failure");
+ return NULL;
+ }
+
+ pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
+ if (pCTX == NULL) {
+ LOGE("SsbSipMfcEncOpen] malloc failed.");
+ close(hMFCOpen);
+ return NULL;
+ }
+ memset(pCTX, 0, sizeof(_MFCLIB));
+
+ mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg);
+ if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) {
+ LOGE("SsbSipMfcEncOpen] IOCTL_MFC_GET_MMAP_SIZE failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0);
+ if (!mapped_addr) {
+ LOGE("SsbSipMfcEncOpen] FIMV5.x driver address mapping failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ pCTX->magic = _MFCLIB_MAGIC_NUMBER;
+ pCTX->hMFC = hMFCOpen;
+ pCTX->mapped_addr = mapped_addr;
+ pCTX->mapped_size = mapped_size;
+ pCTX->inter_buff_status = MFC_USE_NONE;
+
+ return (void *) pCTX;
+}
+
+
+void *SsbSipMfcEncOpenExt(void *value)
+{
+ int hMFCOpen;
+ _MFCLIB *pCTX = NULL;
+ unsigned int mapped_addr;
+ int mapped_size;
+ int err;
+ struct mfc_common_args CommonArg;
+
+ LOGI("[%s] MFC Library Ver %d.%02d",__func__, MFC_LIB_VER_MAJOR, MFC_LIB_VER_MINOR);
+
+#if 0
+ if ((codecType != MPEG4_ENC) &&
+ (codecType != H264_ENC) &&
+ (codecType != H263_ENC)) {
+ LOGE("SsbSipMfcEncOpen] Undefined codec type");
+ return NULL;
+ }
+#endif
+
+ if (access(mfc_dev_name, F_OK) != 0) {
+ LOGE("SsbSipMfcEncOpenExt] MFC device node not exists");
+ return NULL;
+ }
+
+ hMFCOpen = open(mfc_dev_name, O_RDWR | O_NDELAY);
+ if (hMFCOpen < 0) {
+ LOGE("SsbSipMfcEncOpenExt] MFC Open failure");
+ return NULL;
+ }
+
+ pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
+ if (pCTX == NULL) {
+ LOGE("SsbSipMfcEncOpenExt] malloc failed.");
+ close(hMFCOpen);
+ return NULL;
+ }
+ memset(pCTX, 0, sizeof(_MFCLIB));
+
+ CommonArg.args.mem_alloc.buf_cache_type = *(SSBIP_MFC_BUFFER_TYPE *)value;
+
+ err = ioctl(hMFCOpen, IOCTL_MFC_SET_BUF_CACHE, &CommonArg);
+ if ((err < 0) || (CommonArg.ret_code != MFC_OK)) {
+ LOGE("SsbSipMfcEncOpenExt] IOCTL_MFC_SET_BUF_CACHE failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ mapped_size = ioctl(hMFCOpen, IOCTL_MFC_GET_MMAP_SIZE, &CommonArg);
+ if ((mapped_size < 0) || (CommonArg.ret_code != MFC_OK)) {
+ LOGE("SsbSipMfcEncOpenExt] IOCTL_MFC_GET_MMAP_SIZE failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ mapped_addr = (unsigned int)mmap(0, mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0);
+ if (!mapped_addr) {
+ LOGE("SsbSipMfcEncOpenExt] FIMV5.x driver address mapping failed");
+ free(pCTX);
+ close(hMFCOpen);
+ return NULL;
+ }
+
+ pCTX->magic = _MFCLIB_MAGIC_NUMBER;
+ pCTX->hMFC = hMFCOpen;
+ pCTX->mapped_addr = mapped_addr;
+ pCTX->mapped_size = mapped_size;
+ pCTX->inter_buff_status = MFC_USE_NONE;
+
+ return (void *) pCTX;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param)
+{
+ int ret_code;
+
+ _MFCLIB *pCTX;
+ struct mfc_common_args EncArg;
+ SSBSIP_MFC_ENC_H264_PARAM *h264_arg;
+ SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg;
+ SSBSIP_MFC_ENC_H263_PARAM *h263_arg;
+
+ pCTX = (_MFCLIB *) openHandle;
+ memset(&EncArg, 0, sizeof(struct mfc_common_args));
+
+ pCTX->encode_cnt = 0;
+
+ mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param;
+ if (mpeg4_arg->codecType == MPEG4_ENC) {
+ pCTX->codecType= MPEG4_ENC;
+ } else {
+ h263_arg = (SSBSIP_MFC_ENC_H263_PARAM*)param;
+ if (h263_arg->codecType == H263_ENC) {
+ pCTX->codecType = H263_ENC;
+ } else {
+ h264_arg = (SSBSIP_MFC_ENC_H264_PARAM*)param;
+ if (h264_arg->codecType == H264_ENC) {
+ pCTX->codecType = H264_ENC;
+ } else {
+ LOGE("SsbSipMfcEncInit] Undefined codec type");
+ return MFC_RET_INVALID_PARAM;
+ }
+ }
+ }
+
+ LOGI("SsbSipMfcEncInit] Encode Init start");
+
+ switch (pCTX->codecType) {
+ case MPEG4_ENC:
+ LOGI("SsbSipMfcEncInit] MPEG4 Encode");
+ mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param;
+
+ pCTX->width = mpeg4_arg->SourceWidth;
+ pCTX->height = mpeg4_arg->SourceHeight;
+ break;
+
+ case H263_ENC:
+ LOGI("SsbSipMfcEncInit] H263 Encode");
+ h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param;
+
+ pCTX->width = h263_arg->SourceWidth;
+ pCTX->height = h263_arg->SourceHeight;
+ break;
+
+ case H264_ENC:
+ LOGI("SsbSipMfcEncInit] H264 Encode");
+ h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param;
+
+ pCTX->width = h264_arg->SourceWidth;
+ pCTX->height = h264_arg->SourceHeight;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pCTX->codecType) {
+ case MPEG4_ENC:
+ mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param;
+
+ EncArg.args.enc_init.cmn.in_codec_type = pCTX->codecType;
+
+ EncArg.args.enc_init.cmn.in_width = mpeg4_arg->SourceWidth;
+ EncArg.args.enc_init.cmn.in_height = mpeg4_arg->SourceHeight;
+ EncArg.args.enc_init.cmn.in_gop_num = mpeg4_arg->IDRPeriod;
+
+ EncArg.args.enc_init.cmn.in_ms_mode = mpeg4_arg->SliceMode;
+ EncArg.args.enc_init.cmn.in_ms_arg = mpeg4_arg->SliceArgument;
+ EncArg.args.enc_init.cmn.in_output_mode = mpeg4_arg->OutputMode;
+
+ EncArg.args.enc_init.cmn.in_mb_refresh = mpeg4_arg->RandomIntraMBRefresh;
+
+ /* rate control*/
+ EncArg.args.enc_init.cmn.in_rc_fr_en = mpeg4_arg->EnableFRMRateControl;
+ if ((mpeg4_arg->QSCodeMin > 31) || (mpeg4_arg->QSCodeMax > 31)) {
+ LOGE("SsbSipMfcEncInit] No such Min/Max QP is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_rc_qbound_min = mpeg4_arg->QSCodeMin;
+ EncArg.args.enc_init.cmn.in_rc_qbound_max = mpeg4_arg->QSCodeMax;
+ EncArg.args.enc_init.cmn.in_rc_rpara = mpeg4_arg->CBRPeriodRf;
+
+ /* pad control */
+ EncArg.args.enc_init.cmn.in_pad_ctrl_on = mpeg4_arg->PadControlOn;
+ if ((mpeg4_arg->LumaPadVal > 255) || (mpeg4_arg->CbPadVal > 255) || (mpeg4_arg->CrPadVal > 255)) {
+ LOGE("SsbSipMfcEncInit] No such Pad value is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_y_pad_val = mpeg4_arg->LumaPadVal;
+ EncArg.args.enc_init.cmn.in_cb_pad_val = mpeg4_arg->CbPadVal;
+ EncArg.args.enc_init.cmn.in_cr_pad_val = mpeg4_arg->CrPadVal;
+
+ /* Input stream Mode NV12_Linear or NV12_Tile*/
+ EncArg.args.enc_init.cmn.in_frame_map = mpeg4_arg->FrameMap;
+
+ EncArg.args.enc_init.cmn.in_rc_bitrate = mpeg4_arg->Bitrate;
+ if ((mpeg4_arg->FrameQp > 31) || (mpeg4_arg->FrameQp_P > 31)) {
+ LOGE("SsbSipMfcEncInit] No such FrameQp is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_vop_quant = mpeg4_arg->FrameQp;
+ EncArg.args.enc_init.cmn.in_vop_quant_p = mpeg4_arg->FrameQp_P;
+
+ /* MPEG4 only */
+ EncArg.args.enc_init.codec.mpeg4.in_profile = mpeg4_arg->ProfileIDC;
+ EncArg.args.enc_init.codec.mpeg4.in_level = mpeg4_arg->LevelIDC;
+
+ if (mpeg4_arg->FrameQp_B > 31) {
+ LOGE("SsbSipMfcEncInit] No such FrameQp is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.codec.mpeg4.in_vop_quant_b = mpeg4_arg->FrameQp_B;
+
+ if (mpeg4_arg->NumberBFrames > 2) {
+ LOGE("SsbSipMfcEncInit] No such BframeNum is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.codec.mpeg4.in_bframenum = mpeg4_arg->NumberBFrames;
+
+ EncArg.args.enc_init.codec.mpeg4.in_quart_pixel = mpeg4_arg->DisableQpelME;
+
+ EncArg.args.enc_init.codec.mpeg4.in_TimeIncreamentRes = mpeg4_arg->TimeIncreamentRes;
+ EncArg.args.enc_init.codec.mpeg4.in_VopTimeIncreament = mpeg4_arg->VopTimeIncreament;
+
+ break;
+
+ case H263_ENC:
+ h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param;
+
+ EncArg.args.enc_init.cmn.in_codec_type = pCTX->codecType;
+
+ EncArg.args.enc_init.cmn.in_width = h263_arg->SourceWidth;
+ EncArg.args.enc_init.cmn.in_height = h263_arg->SourceHeight;
+ EncArg.args.enc_init.cmn.in_gop_num = h263_arg->IDRPeriod;
+
+ EncArg.args.enc_init.cmn.in_ms_mode = h263_arg->SliceMode;
+ EncArg.args.enc_init.cmn.in_ms_arg = 0;
+ EncArg.args.enc_init.cmn.in_output_mode = FRAME; /* not support to slice output mode */
+
+ EncArg.args.enc_init.cmn.in_mb_refresh = h263_arg->RandomIntraMBRefresh;
+
+ /* rate control*/
+ EncArg.args.enc_init.cmn.in_rc_fr_en = h263_arg->EnableFRMRateControl;
+ if ((h263_arg->QSCodeMin > 31) || (h263_arg->QSCodeMax > 31)) {
+ LOGE("SsbSipMfcEncInit] No such Min/Max QP is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_rc_qbound_min = h263_arg->QSCodeMin;
+ EncArg.args.enc_init.cmn.in_rc_qbound_max = h263_arg->QSCodeMax;
+ EncArg.args.enc_init.cmn.in_rc_rpara = h263_arg->CBRPeriodRf;
+
+ /* pad control */
+ EncArg.args.enc_init.cmn.in_pad_ctrl_on = h263_arg->PadControlOn;
+ if ((h263_arg->LumaPadVal > 255) || (h263_arg->CbPadVal > 255) || (h263_arg->CrPadVal > 255)) {
+ LOGE("SsbSipMfcEncInit] No such Pad value is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_y_pad_val = h263_arg->LumaPadVal;
+ EncArg.args.enc_init.cmn.in_cb_pad_val = h263_arg->CbPadVal;
+ EncArg.args.enc_init.cmn.in_cr_pad_val = h263_arg->CrPadVal;
+
+ /* Input stream Mode NV12_Linear or NV12_Tile*/
+ EncArg.args.enc_init.cmn.in_frame_map = h263_arg->FrameMap;
+
+ EncArg.args.enc_init.cmn.in_rc_bitrate = h263_arg->Bitrate;
+ if ((h263_arg->FrameQp > 31) || (h263_arg->FrameQp_P > 31)) {
+ LOGE("SsbSipMfcEncInit] No such FrameQp is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_vop_quant = h263_arg->FrameQp;
+ EncArg.args.enc_init.cmn.in_vop_quant_p = h263_arg->FrameQp_P;
+
+ /* H.263 only */
+ EncArg.args.enc_init.codec.h263.in_rc_framerate = h263_arg->FrameRate;
+
+ break;
+
+ case H264_ENC:
+ h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param;
+
+ EncArg.args.enc_init.cmn.in_codec_type = H264_ENC;
+
+ EncArg.args.enc_init.cmn.in_width = h264_arg->SourceWidth;
+ EncArg.args.enc_init.cmn.in_height = h264_arg->SourceHeight;
+ EncArg.args.enc_init.cmn.in_gop_num = h264_arg->IDRPeriod;
+
+ if ((h264_arg->SliceMode == 0)||(h264_arg->SliceMode == 1)||
+ (h264_arg->SliceMode == 2)||(h264_arg->SliceMode == 4)) {
+ EncArg.args.enc_init.cmn.in_ms_mode = h264_arg->SliceMode;
+ } else {
+ LOGE("SsbSipMfcEncInit] No such slice mode is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_ms_arg = h264_arg->SliceArgument;
+ EncArg.args.enc_init.cmn.in_output_mode = h264_arg->OutputMode;
+
+ EncArg.args.enc_init.cmn.in_mb_refresh = h264_arg->RandomIntraMBRefresh;
+ /* pad control */
+ EncArg.args.enc_init.cmn.in_pad_ctrl_on = h264_arg->PadControlOn;
+ if ((h264_arg->LumaPadVal > 255) || (h264_arg->CbPadVal > 255) || (h264_arg->CrPadVal > 255)) {
+ LOGE("SsbSipMfcEncInit] No such Pad value is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_y_pad_val = h264_arg->LumaPadVal;
+ EncArg.args.enc_init.cmn.in_cb_pad_val = h264_arg->CbPadVal;
+ EncArg.args.enc_init.cmn.in_cr_pad_val = h264_arg->CrPadVal;
+
+ /* Input stream Mode NV12_Linear or NV12_Tile*/
+ EncArg.args.enc_init.cmn.in_frame_map = h264_arg->FrameMap;
+
+ /* rate control*/
+ EncArg.args.enc_init.cmn.in_rc_fr_en = h264_arg->EnableFRMRateControl;
+ EncArg.args.enc_init.cmn.in_rc_bitrate = h264_arg->Bitrate;
+ if ((h264_arg->FrameQp > 51) || (h264_arg->FrameQp_P > 51)) {
+ LOGE("SsbSipMfcEncInit] No such FrameQp is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_vop_quant = h264_arg->FrameQp;
+ EncArg.args.enc_init.cmn.in_vop_quant_p = h264_arg->FrameQp_P;
+
+ if ((h264_arg->QSCodeMin > 51) || (h264_arg->QSCodeMax > 51)) {
+ LOGE("SsbSipMfcEncInit] No such Min/Max QP is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.cmn.in_rc_qbound_min = h264_arg->QSCodeMin;
+ EncArg.args.enc_init.cmn.in_rc_qbound_max = h264_arg->QSCodeMax;
+ EncArg.args.enc_init.cmn.in_rc_rpara = h264_arg->CBRPeriodRf;
+
+
+ /* H.264 Only */
+ EncArg.args.enc_init.codec.h264.in_profile = h264_arg->ProfileIDC;
+ EncArg.args.enc_init.codec.h264.in_level = h264_arg->LevelIDC;
+
+ if (h264_arg->FrameQp_B > 51) {
+ LOGE("SsbSipMfcEncInit] No such FrameQp is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.codec.h264.in_vop_quant_b = h264_arg->FrameQp_B;
+
+ if (h264_arg->NumberBFrames > 2) {
+ LOGE("SsbSipMfcEncInit] No such BframeNum is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.codec.h264.in_bframenum = h264_arg->NumberBFrames;
+
+ EncArg.args.enc_init.codec.h264.in_interlace_mode = h264_arg->PictureInterlace;
+
+ if ((h264_arg->NumberRefForPframes > 2)||(h264_arg->NumberReferenceFrames >2)) {
+ LOGE("SsbSipMfcEncInit] No such ref Num is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.codec.h264.in_reference_num = h264_arg->NumberReferenceFrames;
+ EncArg.args.enc_init.codec.h264.in_ref_num_p = h264_arg->NumberRefForPframes;
+
+ EncArg.args.enc_init.codec.h264.in_rc_framerate = h264_arg->FrameRate;
+
+ EncArg.args.enc_init.codec.h264.in_rc_mb_en = h264_arg->EnableMBRateControl;
+ EncArg.args.enc_init.codec.h264.in_rc_mb_dark_dis = h264_arg->DarkDisable;
+ EncArg.args.enc_init.codec.h264.in_rc_mb_smooth_dis = h264_arg->SmoothDisable;
+ EncArg.args.enc_init.codec.h264.in_rc_mb_static_dis = h264_arg->StaticDisable;
+ EncArg.args.enc_init.codec.h264.in_rc_mb_activity_dis = h264_arg->ActivityDisable;
+
+ EncArg.args.enc_init.codec.h264.in_deblock_dis = h264_arg->LoopFilterDisable;
+ if ((abs(h264_arg->LoopFilterAlphaC0Offset) > 6) || (abs(h264_arg->LoopFilterBetaOffset) > 6)) {
+ LOGE("SsbSipMfcEncInit] No such AlphaC0Offset or BetaOffset is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+ EncArg.args.enc_init.codec.h264.in_deblock_alpha_c0 = h264_arg->LoopFilterAlphaC0Offset;
+ EncArg.args.enc_init.codec.h264.in_deblock_beta = h264_arg->LoopFilterBetaOffset;
+
+ EncArg.args.enc_init.codec.h264.in_symbolmode = h264_arg->SymbolMode;
+ EncArg.args.enc_init.codec.h264.in_transform8x8_mode = h264_arg->Transform8x8Mode;
+
+ /* FIXME: is it removed? */
+ EncArg.args.enc_init.codec.h264.in_md_interweight_pps = 300;
+ EncArg.args.enc_init.codec.h264.in_md_intraweight_pps = 170;
+
+ break;
+
+ default:
+ LOGE("SsbSipMfcEncInit] No such codec type is supported");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ EncArg.args.enc_init.cmn.in_mapped_addr = pCTX->mapped_addr;
+
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_INIT, &EncArg);
+ if (EncArg.ret_code != MFC_OK) {
+ LOGE("SsbSipMfcEncInit] IOCTL_MFC_ENC_INIT failed");
+ return MFC_RET_ENC_INIT_FAIL;
+ }
+
+ pCTX->virStrmBuf = EncArg.args.enc_init.cmn.out_u_addr.strm_ref_y;
+ pCTX->phyStrmBuf = EncArg.args.enc_init.cmn.out_p_addr.strm_ref_y;
+
+ pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE;
+ pCTX->encodedHeaderSize = EncArg.args.enc_init.cmn.out_header_size;
+
+ pCTX->virMvRefYC = EncArg.args.enc_init.cmn.out_u_addr.mv_ref_yc;
+
+ pCTX->inter_buff_status |= MFC_USE_STRM_BUFF;
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle)
+{
+ int ret_code;
+ _MFCLIB *pCTX;
+ struct mfc_common_args EncArg;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcEncExe] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *)openHandle;
+
+ memset(&EncArg, 0x00, sizeof(struct mfc_common_args));
+
+ EncArg.args.enc_exe.in_codec_type = pCTX->codecType;
+ EncArg.args.enc_exe.in_Y_addr = (unsigned int)pCTX->phyFrmBuf.luma;
+ EncArg.args.enc_exe.in_CbCr_addr = (unsigned int)pCTX->phyFrmBuf.chroma;
+#if 0 /* peter for debug */
+ EncArg.args.enc_exe.in_Y_addr_vir = (unsigned int)pCTX->virFrmBuf.luma;
+ EncArg.args.enc_exe.in_CbCr_addr_vir = (unsigned int)pCTX->virFrmBuf.chroma;
+#endif
+ EncArg.args.enc_exe.in_frametag = pCTX->inframetag;
+ if (pCTX->encode_cnt == 0) {
+ EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf;
+ EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf;
+ } else {
+ EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2);
+ EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2);
+ }
+
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_EXE, &EncArg);
+ if (EncArg.ret_code != MFC_OK) {
+ LOGE("SsbSipMfcEncExe] IOCTL_MFC_ENC_EXE failed(ret : %d)", EncArg.ret_code);
+ return MFC_RET_ENC_EXE_ERR;
+ }
+
+ pCTX->encodedDataSize = EncArg.args.enc_exe.out_encoded_size;
+ pCTX->encodedframeType = EncArg.args.enc_exe.out_frame_type;
+ pCTX->encodedphyFrmBuf.luma = EncArg.args.enc_exe.out_Y_addr;
+ pCTX->encodedphyFrmBuf.chroma = EncArg.args.enc_exe.out_CbCr_addr;
+ pCTX->outframetagtop = EncArg.args.enc_exe.out_frametag_top;
+ pCTX->outframetagbottom = EncArg.args.enc_exe.out_frametag_bottom;
+
+ LOGV("SsbSipMfcEncExe] Encode success ==================");
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle)
+{
+ int ret_code;
+ _MFCLIB *pCTX;
+ struct mfc_common_args free_arg;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcEncClose] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *)openHandle;
+
+ /* FIXME: free buffer? */
+ if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) {
+ free_arg.args.mem_free.key = pCTX->virFrmBuf.luma;
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
+ }
+
+ if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) {
+ free_arg.args.mem_free.key = pCTX->virStrmBuf;
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
+ free_arg.args.mem_free.key = pCTX->virMvRefYC;
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
+ }
+
+ pCTX->inter_buff_status = MFC_USE_NONE;
+
+ munmap((void *)pCTX->mapped_addr, pCTX->mapped_size);
+
+ close(pCTX->hMFC);
+
+ free(pCTX);
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info)
+{
+ int ret_code;
+ _MFCLIB *pCTX;
+ struct mfc_common_args user_addr_arg, real_addr_arg;
+ int y_size, c_size;
+ int aligned_y_size, aligned_c_size;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcEncGetInBuf] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ /* FIXME: */
+ y_size = pCTX->width * pCTX->height;
+ c_size = (pCTX->width * pCTX->height) >> 1;
+
+ /* lenear: 2KB, tile: 8KB */
+ aligned_y_size = Align(y_size, 64 * BUF_L_UNIT);
+ aligned_c_size = Align(c_size, 64 * BUF_L_UNIT);
+
+ /* Allocate luma & chroma buf */
+ user_addr_arg.args.mem_alloc.type = ENCODER;
+ user_addr_arg.args.mem_alloc.buff_size = aligned_y_size + aligned_c_size;
+ user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr;
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg);
+ if (ret_code < 0) {
+ LOGE("SsbSipMfcEncGetInBuf] IOCTL_MFC_GET_IN_BUF failed");
+ return MFC_RET_ENC_GET_INBUF_FAIL;
+ }
+
+ pCTX->virFrmBuf.luma = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset;
+ pCTX->virFrmBuf.chroma = pCTX->mapped_addr + user_addr_arg.args.mem_alloc.offset + (unsigned int)aligned_y_size;
+
+ real_addr_arg.args.real_addr.key = user_addr_arg.args.mem_alloc.offset;
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_REAL_ADDR, &real_addr_arg);
+ if (ret_code < 0) {
+ LOGE("SsbSipMfcEncGetInBuf] IOCTL_MFC_GET_REAL_ADDR failed");
+ return MFC_RET_ENC_GET_INBUF_FAIL;
+ }
+ pCTX->phyFrmBuf.luma = real_addr_arg.args.real_addr.addr;
+ pCTX->phyFrmBuf.chroma = real_addr_arg.args.real_addr.addr + (unsigned int)aligned_y_size;
+
+ pCTX->sizeFrmBuf.luma = (unsigned int)y_size;
+ pCTX->sizeFrmBuf.chroma = (unsigned int)c_size;
+ pCTX->inter_buff_status |= MFC_USE_YUV_BUFF;
+
+ input_info->YPhyAddr = (void*)pCTX->phyFrmBuf.luma;
+ input_info->CPhyAddr = (void*)pCTX->phyFrmBuf.chroma;
+ input_info->YVirAddr = (void*)pCTX->virFrmBuf.luma;
+ input_info->CVirAddr = (void*)pCTX->virFrmBuf.chroma;
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info)
+{
+ _MFCLIB *pCTX;
+ int ret_code;
+ struct mfc_common_args user_addr_arg, real_addr_arg;
+ int y_size, c_size;
+ int aligned_y_size, aligned_c_size;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcEncSetInBuf] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ LOGV("SsbSipMfcEncSetInBuf] input_info->YPhyAddr & input_info->CPhyAddr should be 64KB aligned");
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ /* FIXME: */
+ y_size = pCTX->width * pCTX->height;
+ c_size = (pCTX->width * pCTX->height) >> 1;
+
+ /* lenear: 2KB, tile: 8KB */
+ aligned_y_size = Align(y_size, 64 * BUF_L_UNIT);
+ aligned_c_size = Align(c_size, 64 * BUF_L_UNIT);
+
+ pCTX->phyFrmBuf.luma = (unsigned int)input_info->YPhyAddr;
+ pCTX->phyFrmBuf.chroma = (unsigned int)input_info->CPhyAddr;
+
+ pCTX->sizeFrmBuf.luma = (unsigned int)input_info->YSize;
+ pCTX->sizeFrmBuf.chroma = (unsigned int)input_info->CSize;
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info)
+{
+ _MFCLIB *pCTX;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcEncGetOutBuf] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *)openHandle;
+
+ output_info->headerSize = pCTX->encodedHeaderSize;
+ output_info->dataSize = pCTX->encodedDataSize;
+ output_info->frameType = pCTX->encodedframeType;
+
+ if (pCTX->encode_cnt == 0) {
+ output_info->StrmPhyAddr = (void *)pCTX->phyStrmBuf;
+ output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + pCTX->mapped_addr;
+ } else {
+ output_info->StrmPhyAddr = (unsigned char *)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2);
+ output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + pCTX->mapped_addr + (MAX_ENCODER_OUTPUT_BUFFER_SIZE / 2);
+ }
+
+ pCTX->encode_cnt ++;
+ pCTX->encode_cnt %= 2;
+
+ output_info->encodedYPhyAddr = (void*)pCTX->encodedphyFrmBuf.luma;
+ output_info->encodedCPhyAddr = (void*)pCTX->encodedphyFrmBuf.chroma;
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize)
+{
+ _MFCLIB *pCTX;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcEncSetOutBuf] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ pCTX->phyStrmBuf = (int)phyOutbuf;
+ pCTX->virStrmBuf = (int)virOutbuf;
+ pCTX->sizeStrmBuf = outputBufferSize;
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value)
+{
+ int ret_code;
+ _MFCLIB *pCTX;
+ struct mfc_common_args EncArg;
+ struct mfc_enc_vui_info vui_info;
+ struct mfc_enc_hier_p_qp hier_p_qp;
+#ifdef S3D_SUPPORT
+ struct mfc_enc_set_config set_info;
+ struct mfc_frame_packing *frame_packing;
+#endif
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcEncSetConfig] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ if (value == NULL) {
+ LOGE("SsbSipMfcEncSetConfig] value is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+ memset(&EncArg, 0x00, sizeof(struct mfc_common_args));
+
+#ifdef S3D_SUPPORT
+ EncArg.args.config.type = conf_type;
+
+ switch (conf_type) {
+ case MFC_ENC_SETCONF_FRAME_TAG:
+ pCTX->inframetag = *((unsigned int *)value);
+ return MFC_RET_OK;
+ case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP:
+ set_info = *((struct mfc_enc_set_config *) value);
+ EncArg.args.config.args.basic.values[0] = set_info.enable;
+ if (set_info.enable == 2)
+ EncArg.args.config.args.basic.values[1] = set_info.number;
+ else
+ EncArg.args.config.args.basic.values[1] = 0;
+ break;
+ case MFC_ENC_SETCONF_VUI_INFO:
+ set_info = *((struct mfc_enc_set_config *) value);
+ EncArg.args.config.args.basic.values[0] = set_info.enable;
+ if (set_info.enable == 255) //Re-check this part of code with Jeongtae Park
+ EncArg.args.config.args.basic.values[1] = set_info.number;
+ else
+ EncArg.args.config.args.basic.values[1] = 0;
+
+ EncArg.args.config.args.basic.values[1] = set_info.number;
+ break;
+ case MFC_ENC_SETCONF_FRAME_PACKING:
+ frame_packing = (struct mfc_frame_packing *)value;
+ /*
+ memcpy(&EncArg.args.config.args.frame_packing, frame_packing,
+ sizeof(struct mfc_frame_packing));
+ */
+ EncArg.args.config.args.basic.values[0] = frame_packing->arrangement_type;
+ EncArg.args.config.args.basic.values[1] = frame_packing->current_frame_is_frame0_flag;
+ break;
+ case MFC_ENC_SETCONF_FRAME_TYPE:
+ case MFC_ENC_SETCONF_CHANGE_FRAME_RATE:
+ case MFC_ENC_SETCONF_CHANGE_BIT_RATE:
+ case MFC_ENC_SETCONF_I_PERIOD:
+ case MFC_ENC_SETCONF_HIER_P:
+ case MFC_ENC_SETCONF_SEI_GEN:
+ EncArg.args.config.args.basic.values[0] = *((int *) value);
+ EncArg.args.config.args.basic.values[1] = 0;
+ break;
+ default:
+ LOGE("SsbSipMfcEncSetConfig] not supported type");
+ return MFC_RET_ENC_SET_CONF_FAIL;
+ }
+#else
+ EncArg.args.set_config.in_config_param = conf_type;
+ switch (conf_type) {
+ case MFC_ENC_SETCONF_FRAME_TAG:
+ pCTX->inframetag = *((unsigned int *)value);
+ return MFC_RET_OK;
+ 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;
+ case MFC_ENC_SETCONF_HIER_P:
+ hier_p_qp = *((struct mfc_enc_hier_p_qp *) value);
+ EncArg.args.set_config.in_config_value[0] = (int)(hier_p_qp.t0_frame_qp);
+ EncArg.args.set_config.in_config_value[1] = (int)(hier_p_qp.t2_frame_qp);
+ EncArg.args.set_config.in_config_value[2] = (int)(hier_p_qp.t3_frame_qp);
+ break;
+ default:
+ EncArg.args.set_config.in_config_value[0] = *((int *) value);
+ EncArg.args.set_config.in_config_value[1] = 0;
+ break;
+ }
+#endif
+
+ ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &EncArg);
+ if (EncArg.ret_code != MFC_OK) {
+ LOGE("SsbSipMfcEncSetConfig] IOCTL_MFC_SET_CONFIG failed(ret : %d)", EncArg.ret_code);
+ 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;
+ /*
+ unsigned int *encoded_header_size;
+ */
+
+ pCTX = (_MFCLIB *)openHandle;
+
+ if (openHandle == NULL) {
+ LOGE("SsbSipMfcEncGetConfig] openHandle is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+ if (value == NULL) {
+ LOGE("SsbSipMfcEncGetConfig] value is NULL");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ switch (conf_type) {
+ case MFC_ENC_GETCONF_FRAME_TAG:
+ *((unsigned int *)value) = pCTX->outframetagtop;
+ break;
+#if 0
+ case MFC_ENC_GETCONF_HEADER_SIZE:
+ encoded_header_size = (unsigned int *)value;
+ *encoded_header_size = pCTX->encodedHeaderSize;
+ break;
+#endif
+ default:
+ LOGE("SsbSipMfcEncGetConfig] No such conf_type is supported.");
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ return MFC_RET_OK;
+}
+
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/SsbSipMfcApi.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/SsbSipMfcApi.h
new file mode 100644
index 0000000..fed3e34
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/SsbSipMfcApi.h
@@ -0,0 +1,420 @@
+/*
+ * 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 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/s3c-mfc"
+
+
+/*--------------------------------------------------------------------------------*/
+/* 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,
+ 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,
+#ifndef S3D_SUPPORT
+ MFC_DEC_GETCONF_WIDTH_HEIGHT
+#else
+ MFC_DEC_GETCONF_WIDTH_HEIGHT,
+ 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,
+#ifndef S3D_SUPPORT
+ MFC_ENC_SETCONF_HIER_P
+#else
+ MFC_ENC_SETCONF_HIER_P,
+ MFC_ENC_SETCONF_SEI_GEN,
+ MFC_ENC_SETCONF_FRAME_PACKING
+#endif
+} 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 */
+
+ /* 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) */
+
+ /* 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 SsbSipMfcDecClose(void *openHandle);
+void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize);
+
+
+#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);
+
+void *SsbSipMfcDecAllocInputBuffer(void *openHandle, void **phyInBuf, int inputBufferSize);
+void SsbSipMfcDecFreeInputBuffer(void *openHandle, void *phyInBuf);
+
+/*--------------------------------------------------------------------------------*/
+/* 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/exynos4/mfc/include/mfc_errno.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_errno.h
new file mode 100644
index 0000000..305a28e
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/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/exynos4/mfc/include/mfc_interface.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_interface.h
new file mode 100644
index 0000000..5212dc1
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc/include/mfc_interface.h
@@ -0,0 +1,526 @@
+/*
+ * 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 __FILE__
+
+#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))
+
+enum inst_type {
+ DECODER = 0x1,
+ ENCODER = 0x2,
+};
+
+typedef enum {
+ MFC_UNPACKED_PB = 0,
+ MFC_PACKED_PB = 1
+} mfc_packed_mode;
+
+
+typedef enum
+{
+ MFC_USE_NONE = 0x00,
+ MFC_USE_YUV_BUFF = 0x01,
+ MFC_USE_STRM_BUFF = 0x10
+} 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;
+
+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;
+
+ SSBSIP_MFC_OUTSTRM_MODE_TYPE in_output_mode;
+
+ 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 */
+};
+
+#ifdef S3D_SUPPORT
+struct mfc_basic_config {
+ int values[4];
+};
+
+struct mfc_frame_packing {
+ 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;
+};
+
+union _mfc_config_arg {
+ struct mfc_basic_config basic;
+ struct mfc_frame_packing frame_packing;
+};
+
+struct mfc_config_arg {
+ int type;
+ union _mfc_config_arg args;
+};
+#else
+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];
+};
+#endif
+
+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;
+
+#ifdef S3D_SUPPORT
+ struct mfc_config_arg config;
+#else
+ struct mfc_get_config_arg get_config;
+ struct mfc_set_config_arg set_config;
+#endif
+
+ 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_set_config {
+ int enable;
+ int number;
+};
+#endif
+
+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;
+} _MFCLIB;
+
+#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8))
+#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8))
+
+#endif /* __MFC_INTERFACE_H */
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/Android.mk
new file mode 100644
index 0000000..f135163
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/Android.mk
@@ -0,0 +1,34 @@
+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_USES_MFC_FPS),true)
+LOCAL_CFLAGS := -DCONFIG_MFC_FPS
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES :=
+LOCAL_SHARED_LIBRARIES := liblog
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c
new file mode 100644
index 0000000..510a351
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/dec/src/SsbSipMfcDecAPI.c
@@ -0,0 +1,1352 @@
+/*
+ * 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"
+
+/* #define LOG_NDEBUG 0 */
+#define LOG_TAG "MFC_DEC_APP"
+#include <utils/Log.h>
+
+#ifdef CONFIG_MFC_FPS
+#include <sys/time.h>
+#endif
+
+/*#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)
+
+#ifdef CONFIG_MFC_FPS
+unsigned int framecount, over30ms;
+struct timeval mTS1, mTS2, mDec1, mDec2;
+#endif
+
+#define DEFAULT_NUMBER_OF_EXTRA_DPB 5
+
+static char *mfc_dev_name = SAMSUNG_MFC_DEV_NAME;
+static int mfc_dev_node = 6;
+
+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;
+ unsigned int i, j;
+ struct v4l2_capability cap;
+ struct v4l2_format fmt;
+
+ struct v4l2_requestbuffers reqbuf;
+ 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);
+#ifdef CONFIG_MFC_FPS
+ framecount = 0;
+ over30ms = 0;
+ gettimeofday(&mTS1, NULL);
+#endif
+ 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;
+
+ memset(&cap, 0, sizeof(cap));
+ ret = ioctl(pCTX->hMFC, VIDIOC_QUERYCAP, &cap);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QUERYCAP failed",__func__);
+ goto error_case2;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
+ LOGE("[%s] Device does not support capture",__func__);
+ goto error_case2;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
+ LOGE("[%s] Device does not support output",__func__);
+ goto error_case2;
+ }
+
+ if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
+ LOGE("[%s] Device does not support streaming",__func__);
+ goto error_case2;
+ }
+
+ pCTX->inter_buff_status = MFC_USE_NONE;
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; /* Default is set to H264 */
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_DECODER_INPUT_BUFFER_SIZE;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt);
+ if (ret != 0) {
+ LOGE("[%s] S_FMT failed",__func__);
+ goto error_case2;
+ }
+
+ pCTX->v4l2_dec.mfc_src_bufs_len = MAX_DECODER_INPUT_BUFFER_SIZE;
+
+ memset(&(reqbuf), 0, sizeof (reqbuf));
+ reqbuf.count = MFC_DEC_NUM_SRC_BUFS;
+ reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ reqbuf.memory = V4L2_MEMORY_MMAP;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_REQBUFS, &reqbuf);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_REQBUFS failed",__func__);
+ goto error_case2;
+ }
+
+ pCTX->v4l2_dec.mfc_num_src_bufs = reqbuf.count;
+
+ for (i = 0; i < pCTX->v4l2_dec.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 = 1;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &buf);
+ 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;
+
+ enum v4l2_buf_type type;
+#ifdef CONFIG_MFC_FPS
+ LOGI(">>> MFC");
+ gettimeofday(&mTS2, NULL);
+ LOGI(">>> time=%d", mTS2.tv_sec-mTS1.tv_sec);
+ LOGI(">>> framecount=%d", framecount);
+ LOGI(">>> 30ms over=%d", over30ms);
+#endif
+ 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->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);
+ }
+
+ 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;
+ unsigned int i, j;
+
+ struct v4l2_requestbuffers reqbuf;
+ struct v4l2_buffer qbuf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+
+ struct v4l2_format fmt;
+ struct v4l2_pix_format_mplane pix_mp;
+ struct v4l2_control ctrl;
+ struct v4l2_crop crop;
+ enum v4l2_buf_type type;
+
+ 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);
+
+ memset(&fmt, 0, sizeof(fmt));
+
+ switch (pCTX->codecType) {
+ 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 = pCTX->fimv1_res.width;
+ fmt.fmt.pix_mp.height = pCTX->fimv1_res.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;
+ default:
+ LOGE("[%s] Does NOT support the standard (%d)",__func__,pCTX->codecType);
+ ret = MFC_RET_INVALID_PARAM;
+ goto error_case1;
+ }
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_DECODER_INPUT_BUFFER_SIZE;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_S_FMT, &fmt);
+ if (ret != 0) {
+ LOGE("[%s] S_FMT failed",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ memset(&qbuf, 0, sizeof(qbuf));
+
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.index = pCTX->v4l2_dec.beingUsedIndex;
+ qbuf.m.planes = planes;
+ qbuf.length = 1;
+ qbuf.m.planes[0].bytesused = Frameleng;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_QBUF failed, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+
+ // Processing the header requires running streamon
+ // on OUTPUT queue
+ ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type);
+ 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;
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_FMT, &fmt);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_FMT failed",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ 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;
+
+ memset(&crop, 0, sizeof(crop));
+ crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_CROP, &crop);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CROP failed",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ 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;
+
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.id = V4L2_CID_CODEC_REQ_NUM_BUFS;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ pCTX->v4l2_dec.mfc_num_dst_bufs = ctrl.value + pCTX->dec_numextradpb;
+
+ /* 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_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ memset(&reqbuf, 0, sizeof(reqbuf));
+ reqbuf.count = pCTX->v4l2_dec.mfc_num_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] VIDIOC_REQBUFS failed (destination buffers)",__func__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ pCTX->v4l2_dec.mfc_num_dst_bufs = reqbuf.count;
+
+ for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) {
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.index = i;
+ qbuf.m.planes = planes;
+ qbuf.length = 2;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QUERYBUF, &qbuf);
+ 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] = qbuf.m.planes[0].length;
+ pCTX->v4l2_dec.mfc_dst_bufs_len[1] = qbuf.m.planes[1].length;
+
+ pCTX->v4l2_dec.mfc_dst_phys[i][0] = qbuf.m.planes[0].cookie;
+ pCTX->v4l2_dec.mfc_dst_phys[i][1] = qbuf.m.planes[1].cookie;
+
+ pCTX->v4l2_dec.mfc_dst_bufs[i][0] = mmap(NULL, qbuf.m.planes[0].length,
+ PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, qbuf.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, qbuf.m.planes[1].length,
+ PROT_READ | PROT_WRITE, MAP_SHARED, pCTX->hMFC, qbuf.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;
+ }
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf);
+ 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;
+
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type);
+ 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;
+
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ 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__);
+ ret = MFC_RET_DEC_INIT_FAIL;
+ goto error_case1;
+ }
+
+ return MFC_RET_OK;
+
+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:
+ SsbSipMfcDecClose(openHandle);
+ return ret;
+}
+
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill)
+{
+ _MFCLIB *pCTX;
+ int ret;
+ struct v4l2_buffer qbuf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+
+ struct pollfd poll_events;
+ int poll_state;
+
+#ifdef CONFIG_MFC_FPS
+ framecount++;
+#endif
+ 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;
+ }
+
+#ifdef CONFIG_MFC_FPS
+ gettimeofday(&mDec1, NULL);
+#endif
+ pCTX = (_MFCLIB *) openHandle;
+
+ /* note: #define POLLOUT 0x0004 */
+ poll_events.fd = pCTX->hMFC;
+ poll_events.events = POLLOUT | POLLERR;
+ poll_events.revents = 0;
+
+ if ((lengthBufFill > 0) && (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe)) {
+ /* Queue the stream frame */
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.index = pCTX->v4l2_dec.beingUsedIndex;
+ qbuf.m.planes = planes;
+ qbuf.length = 1;
+ qbuf.m.planes[0].bytesused = lengthBufFill;
+
+ 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_DEC_EXE_ERR;
+ }
+
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.m.planes = planes;
+ qbuf.length = 1;
+
+ /* wait for decoding */
+ do {
+ poll_state = poll((struct pollfd*)&poll_events, 1, POLL_DEC_WAIT_TIMEOUT);
+ if (0 < poll_state) {
+ if (poll_events.revents & POLLOUT) { /* POLLOUT */
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+ if (ret == 0) {
+ if (qbuf.flags & V4L2_BUF_FLAG_ERROR)
+ return MFC_RET_DEC_EXE_ERR;
+ break;
+ }
+ } else if (poll_events.revents & POLLERR) { /* POLLERR */
+ LOGE("[%s] POLLERR\n",__func__);
+ return MFC_RET_DEC_EXE_ERR;
+ } else {
+ LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents);
+ return MFC_RET_DEC_EXE_ERR;
+ }
+ } else if (0 > poll_state) {
+ return MFC_RET_DEC_EXE_ERR;
+ }
+ } while (0 == poll_state);
+
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.m.planes = planes;
+ qbuf.length = MFC_DEC_NUM_PLANES;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+
+ if (ret != 0) {
+ pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY;
+ pCTX->decOutInfo.disp_pic_frame_type = -1;
+ return MFC_RET_OK;
+ } else {
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING;
+ }
+
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.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;
+
+ /* Queue the stream frame */
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.index = pCTX->v4l2_dec.beingUsedIndex;
+ qbuf.m.planes = planes;
+ qbuf.length = 1;
+ qbuf.m.planes[0].bytesused = 0;
+
+ 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_DEC_EXE_ERR;
+ }
+
+ pCTX->v4l2_dec.bBeingFinalized = 1; /* true */
+
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.m.planes = planes;
+ qbuf.length = MFC_DEC_NUM_PLANES;
+ /* FIXME
+ wait for decoding */
+ do {
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+ } while (ret != 0);
+
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY;
+
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1];
+ } else {
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.m.planes = planes;
+ qbuf.length = MFC_DEC_NUM_PLANES;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+
+ if (qbuf.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[qbuf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1];
+ }
+
+ pCTX->decOutInfo.disp_pic_frame_type = (qbuf.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 = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf);
+
+#ifdef CONFIG_MFC_FPS
+ gettimeofday(&mDec2, NULL);
+ if (mDec2.tv_usec-mDec1.tv_usec > 30000) over30ms++;
+#endif
+ return MFC_RET_OK;
+}
+
+#if 0
+SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExeNb(void *openHandle, int lengthBufFill)
+{
+ _MFCLIB *pCTX;
+ int ret;
+
+ struct v4l2_buffer qbuf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+
+#ifdef CONFIG_MFC_FPS
+ framecount++;
+#endif
+ 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)) {
+ /* Queue the stream frame */
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.index = pCTX->v4l2_dec.beingUsedIndex;
+ qbuf.m.planes = planes;
+ qbuf.length = 1;
+ qbuf.m.planes[0].bytesused = lengthBufFill;
+
+ 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_DEC_EXE_ERR;
+ }
+ } else if(pCTX->v4l2_dec.bBeingFinalized == 0) {
+ /* Queue the stream frame */
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.index = pCTX->v4l2_dec.beingUsedIndex;
+ qbuf.m.planes = planes;
+ qbuf.length = 1;
+ qbuf.m.planes[0].bytesused = 0;
+
+ 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_DEC_EXE_ERR;
+ }
+ }
+
+ if ((SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) && (lengthBufFill == 0))
+ pCTX->lastframe = SSBSIP_MFC_LAST_FRAME_RECEIVED;
+
+ return MFC_RET_OK;
+}
+
+SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecWaitForOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info)
+{
+ _MFCLIB *pCTX;
+ int ret;
+
+ struct v4l2_buffer qbuf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+
+ struct pollfd poll_events;
+ int poll_state;
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ /* note: #define POLLOUT 0x0004 */
+ poll_events.fd = pCTX->hMFC;
+ poll_events.events = POLLOUT | POLLERR;
+ poll_events.revents = 0;
+
+ if (SSBSIP_MFC_LAST_FRAME_PROCESSED != pCTX->lastframe) {
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.m.planes = planes;
+ qbuf.length = 1;
+
+ /* wait for decoding */
+ do {
+ poll_state = poll((struct pollfd*)&poll_events, 1, POLL_DEC_WAIT_TIMEOUT);
+ if (0 < poll_state) {
+ if (poll_events.revents & POLLOUT) { /* POLLOUT */
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+ if (ret == 0) {
+ if (qbuf.flags & V4L2_BUF_FLAG_ERROR)
+ return MFC_GETOUTBUF_STATUS_NULL;
+ break;
+ }
+ } else if (poll_events.revents & POLLERR) { /* POLLERR */
+ LOGE("[%s] POLLERR\n",__func__);
+ return MFC_GETOUTBUF_STATUS_NULL;
+ } else {
+ LOGE("[%s] poll() returns 0x%x\n",__func__, poll_events.revents);
+ return MFC_GETOUTBUF_STATUS_NULL;
+ }
+ } else if (0 > poll_state) {
+ return MFC_GETOUTBUF_STATUS_NULL;
+ }
+ } while (0 == poll_state);
+
+ pCTX->v4l2_dec.mfc_src_buf_flags[qbuf.index] = BUF_DEQUEUED;
+
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.m.planes = planes;
+ qbuf.length = MFC_DEC_NUM_PLANES;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+
+ if (ret != 0) {
+ pCTX->displayStatus = MFC_GETOUTBUF_DECODING_ONLY;
+ pCTX->decOutInfo.disp_pic_frame_type = -1;
+ return SsbSipMfcDecGetOutBuf(pCTX, output_info);;
+ } else {
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_DECODING;
+ }
+
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.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 */
+
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.m.planes = planes;
+ qbuf.length = MFC_DEC_NUM_PLANES;
+
+ /* wait for decoding */
+ do {
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+ } while (ret != 0);
+
+ pCTX->displayStatus = MFC_GETOUTBUF_DISPLAY_ONLY;
+
+ pCTX->decOutInfo.YVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1];
+ } else {
+ memset(&qbuf, 0, sizeof(qbuf));
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.m.planes = planes;
+ qbuf.length = MFC_DEC_NUM_PLANES;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_DQBUF, &qbuf);
+
+ if (qbuf.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[qbuf.index][0];
+ pCTX->decOutInfo.CVirAddr = pCTX->v4l2_dec.mfc_dst_bufs[qbuf.index][1];
+
+ pCTX->decOutInfo.YPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][0];
+ pCTX->decOutInfo.CPhyAddr = (unsigned int)pCTX->v4l2_dec.mfc_dst_phys[qbuf.index][1];
+ }
+
+ pCTX->decOutInfo.disp_pic_frame_type = (qbuf.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 = ioctl(pCTX->hMFC, VIDIOC_QBUF, &qbuf);
+
+ return SsbSipMfcDecGetOutBuf(pCTX, output_info);
+}
+#endif
+
+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];
+ /* 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)
+{
+ int ret;
+ _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:
+#ifdef SSB_UMP
+ ret = ump_secure_id_get_from_vaddr(pCTX->decOutInfo.YVirAddr, &output_info->y_cookie);
+ if (ret) {
+ LOGV("[%s] fail to get secure id(%d) from vaddr(%x)\n",__func__, \
+ output_info->y_cookie, pCTX->decOutInfo.YVirAddr);
+ }
+
+ ret = ump_secure_id_get_from_vaddr(pCTX->decOutInfo.CVirAddr, &output_info->c_cookie);
+ if (ret) {
+ LOGV("[%s] fail to get secure id(%d) from vaddr(%x)\n",__func__, \
+ output_info->c_cookie, pCTX->decOutInfo.CVirAddr);
+ }
+ break;
+#endif
+ 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 qbuf;
+ struct v4l2_plane planes[MFC_DEC_NUM_PLANES];
+ struct v4l2_control ctrl;
+
+ enum v4l2_buf_type type;
+
+ 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:
+ 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_DEC_SET_CONF_FAIL;
+ }
+ pCTX->inter_buff_status &= ~(MFC_USE_DST_STREAMON);
+
+ for (i = 0; i < pCTX->v4l2_dec.mfc_num_dst_bufs; ++i) {
+ memset(&qbuf, 0, sizeof(qbuf));
+
+ qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ qbuf.memory = V4L2_MEMORY_MMAP;
+ qbuf.index = i;
+ 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_CAPTURE_MPLANE",__func__);
+ return MFC_RET_DEC_SET_CONF_FAIL;
+ }
+ }
+
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ ret = ioctl(pCTX->hMFC, VIDIOC_STREAMON, &type);
+ 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 */
+ memset(&ctrl, 0, sizeof(ctrl));
+ switch (conf_type) {
+ case MFC_DEC_SETCONF_DISPLAY_DELAY: /* be set before calling SsbSipMfcDecInit */
+ ctrl.id = V4L2_CID_CODEC_DISPLAY_DELAY;
+ ctrl.value = *((unsigned int *) value);
+ break;
+
+ case MFC_DEC_SETCONF_CRC_ENABLE:
+ ctrl.id = V4L2_CID_CODEC_CRC_ENABLE;
+ ctrl.value = 1;
+ break;
+
+ case MFC_DEC_SETCONF_SLICE_ENABLE:
+ ctrl.id = V4L2_CID_CODEC_SLICE_INTERFACE;
+ ctrl.value = 1;
+ break;
+
+ case MFC_DEC_SETCONF_FRAME_TAG: /*be set before calling SsbSipMfcDecExe */
+ ctrl.id = V4L2_CID_CODEC_FRAME_TAG;
+ ctrl.value = *((unsigned int*)value);
+ break;
+
+ case MFC_DEC_SETCONF_POST_ENABLE:
+ ctrl.id = V4L2_CID_CODEC_LOOP_FILTER_MPEG4_ENABLE;
+ ctrl.value = *((unsigned int*)value);
+ break;
+
+ default:
+ LOGE("[%s] conf_type(%d) is NOT supported",__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_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;
+ SSBSIP_MFC_CROP_INFORMATION *crop_information;
+ struct v4l2_control ctrl;
+
+ 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_CRC_DATA:
+ crc_data = (SSBSIP_MFC_CRC_DATA *) value;
+
+ ctrl.id = V4L2_CID_CODEC_CRC_DATA_LUMA;
+ ctrl.value = 0;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_LUMA",__func__);
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+ crc_data->luma0 = ctrl.value;
+
+ ctrl.id = V4L2_CID_CODEC_CRC_DATA_CHROMA;
+ ctrl.value = 0;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl);
+ if (ret != 0) {
+ LOGE("[%s] VIDIOC_G_CTRL failed, V4L2_CID_CODEC_CRC_DATA_CHROMA",__func__);
+ return MFC_RET_DEC_GET_CONF_FAIL;
+ }
+ crc_data->chroma0 = ctrl.value;
+
+ LOGI("[%s] crc_data->luma0=%d",__func__,ctrl.value);
+ LOGI("[%s] crc_data->chroma0=%d",__func__,ctrl.value);
+ break;
+
+ case MFC_DEC_GETCONF_FRAME_TAG:
+ ctrl.id = V4L2_CID_CODEC_FRAME_TAG;
+ ctrl.value = 0;
+
+ ret = ioctl(pCTX->hMFC, VIDIOC_G_CTRL, &ctrl);
+ if (ret != 0) {
+ printf("Error to do g_ctrl.\n");
+ }
+ *((unsigned int *)value) = ctrl.value;
+ break;
+
+ 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/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c
new file mode 100644
index 0000000..45888c6
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/enc/src/SsbSipMfcEncAPI.c
@@ -0,0 +1,1206 @@
+/*
+ * 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;
+
+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;
+
+ 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 i;
+
+ if (openHandle == NULL) {
+ LOGE("[%s] openHandle is NULL",__func__);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ pCTX = (_MFCLIB *) openHandle;
+
+ 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[27];
+ struct v4l2_ext_control ext_ctrl_h263[19];
+ struct v4l2_ext_control ext_ctrl[44];
+ 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 */
+ ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl_mpeg4[6].value = 1900; /* default */
+ } 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;
+ ext_ctrl_mpeg4[6].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl_mpeg4[6].value = 1900; /* default */
+ } 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;
+ 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;
+ 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 */
+ ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl[7].value = 1900; /* default */
+ } 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;
+ ext_ctrl[7].id = V4L2_CID_CODEC_MFC5X_ENC_MULTI_SLICE_BIT;
+ ext_ctrl[7].value = 1900; /* default */
+ } 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_RC_FIXED_TARGET_BIT;
+ ext_ctrl[39].value = V4L2_CODEC_MFC5X_ENC_SW_ENABLE;
+
+ ext_ctrl[40].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_ENABLE;
+ ext_ctrl[40].value = V4L2_CODEC_MFC5X_ENC_SW_DISABLE;
+ ext_ctrl[41].id = V4L2_CID_CODEC_MFC5X_ENC_H264_AR_VUI_IDC;
+ ext_ctrl[41].value = 0;
+ ext_ctrl[42].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_WIDTH;
+ ext_ctrl[42].value = 0;
+ ext_ctrl[43].id = V4L2_CID_CODEC_MFC5X_ENC_H264_EXT_SAR_HEIGHT;
+ ext_ctrl[43].value = 0;
+
+ 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 = 27;
+ ext_ctrls.controls = ext_ctrl_mpeg4;
+ } else if (pCTX->codecType == H264_ENC) {
+ ext_ctrls.count = 44;
+ ext_ctrls.controls = ext_ctrl;
+ } else if (pCTX->codecType == H263_ENC) {
+ ext_ctrls.count = 19;
+ 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;
+ 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 */
+ }
+
+ 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;
+ }
+
+ 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 (0 == poll_state);
+
+ pCTX->v4l2_enc.mfc_dst_bufs_bytes_used_len = buf.m.planes[0].bytesused;
+ pCTX->virStrmBuf = 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;
+
+ 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;
+
+ 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 {
+ /* FIXME check this for correct physical address */
+ 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;
+
+ 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;
+ }
+
+ 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*)0;
+ output_info->encodedCPhyAddr = (void*)0;
+
+ 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;
+ }
+
+ 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;
+ }
+ loopcnt++;
+ } while ((0 == poll_state) && (loopcnt < 5));
+
+ if (pCTX->v4l2_enc.bRunning != 0) {
+ pCTX->encodedframeType = (qbuf.flags & 0x18) >> 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 = 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;
+
+ 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_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;
+
+ case MFC_ENC_SETCONF_HIER_P:
+ hier_p_qp = *((struct mfc_enc_hier_p_qp *) value);
+ EncArg.args.set_config.in_config_value[0] = (int)(hier_p_qp.t0_frame_qp);
+ EncArg.args.set_config.in_config_value[1] = (int)(hier_p_qp.t2_frame_qp);
+ EncArg.args.set_config.in_config_value[2] = (int)(hier_p_qp.t3_frame_qp);
+ break;
+
+ case MFC_ENC_SETCONF_I_PERIOD:
+#endif
+ default:
+ LOGE("[%s] conf_type(%d) is NOT supported\n",__func__, conf_type);
+ return MFC_RET_INVALID_PARAM;
+ }
+
+ 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/exynos4/mfc_v4l2/include/SsbSipMfcApi.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h
new file mode 100644
index 0000000..b85256b
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/SsbSipMfcApi.h
@@ -0,0 +1,382 @@
+/*
+ * 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 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,
+ 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 {
+ 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
+} 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
+} 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) */
+
+ /* 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) */
+
+ /* 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) */
+
+ /* 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 __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/exynos4/mfc_v4l2/include/mfc_errno.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_errno.h
new file mode 100644
index 0000000..b8e96ab
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/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/exynos4/mfc_v4l2/include/mfc_interface.h b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h
new file mode 100644
index 0000000..b7289c4
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos4/mfc_v4l2/include/mfc_interface.h
@@ -0,0 +1,541 @@
+/*
+ * 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,
+};
+
+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;
+
+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;
+};
+
+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;
+} _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 */
diff --git a/exynos4/multimedia/codecs/sec_codecs/video/exynos5/Android.mk b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/Android.mk
new file mode 100644
index 0000000..949c637
--- /dev/null
+++ b/exynos4/multimedia/codecs/sec_codecs/video/exynos5/Android.mk
@@ -0,0 +1,7 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_VIDEO_PATH :=$(LOCAL_PATH)
+
+include $(LOCAL_VIDEO_PATH)/mfc_v4l2/Android.mk
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 */