hardware/qcom/media: Initial commit
- Includes modules : libstagefrighthw, mm-core, mm-video
- libstagefrighthw: Adds OMX plugins for QCom component
- mm-core: Registers QCom component
- mm-video: Decoder and encoder component
Change-Id: I3ba599ac1c8652dc5fc2f3825f6e6ab8047be347
diff --git a/mm-video/vidc/venc/Android.mk b/mm-video/vidc/venc/Android.mk
new file mode 100755
index 0000000..d2dfe40
--- /dev/null
+++ b/mm-video/vidc/venc/Android.mk
@@ -0,0 +1,133 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+ROOT_DIR := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PATH:= $(ROOT_DIR)
+
+# ---------------------------------------------------------------------------------
+# Common definitons
+# ---------------------------------------------------------------------------------
+
+libmm-venc-def := -g -O3 -Dlrintf=_ffix_r
+libmm-venc-def += -D__align=__alignx
+libmm-venc-def += -D__alignx\(x\)=__attribute__\(\(__aligned__\(x\)\)\)
+libmm-venc-def += -DT_ARM
+libmm-venc-def += -Dinline=__inline
+libmm-venc-def += -D_ANDROID_
+libmm-venc-def += -UENABLE_DEBUG_LOW
+libmm-venc-def += -DENABLE_DEBUG_HIGH
+libmm-venc-def += -DENABLE_DEBUG_ERROR
+libmm-venc-def += -UINPUT_BUFFER_LOG
+libmm-venc-def += -UOUTPUT_BUFFER_LOG
+libmm-venc-def += -USINGLE_ENCODER_INSTANCE
+ifeq ($(TARGET_BOARD_PLATFORM),msm8660)
+libmm-venc-def += -DMAX_RES_1080P
+endif
+ifeq ($(TARGET_BOARD_PLATFORM),msm8960)
+libmm-venc-def += -DMAX_RES_1080P
+libmm-venc-def += -DMAX_RES_1080P_EBI
+endif
+ifeq ($(TARGET_BOARD_PLATFORM),msm8974)
+libmm-venc-def += -DMAX_RES_1080P
+libmm-venc-def += -DMAX_RES_1080P_EBI
+libmm-venc-def += -DBADGER
+endif
+ifeq ($(TARGET_USES_ION),true)
+libmm-venc-def += -DUSE_ION
+endif
+libmm-venc-def += -D_ANDROID_ICS_
+# ---------------------------------------------------------------------------------
+# Make the Shared library (libOmxVenc)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+libmm-venc-inc := bionic/libc/include
+libmm-venc-inc += bionic/libstdc++/include
+libmm-venc-inc := $(LOCAL_PATH)/inc
+libmm-venc-inc += $(OMX_VIDEO_PATH)/vidc/common/inc
+libmm-venc-inc += hardware/qcom/media/mm-core/inc
+#libmm-venc-inc += bionic/libc/kernel/common/linux
+libmm-venc-inc += hardware/qcom/media/libstagefrighthw
+libmm-venc-inc += hardware/qcom/display/libgralloc
+libmm-venc-inc += frameworks/native/include/media/hardware
+libmm-venc-inc += frameworks/native/include/media/openmax
+
+
+LOCAL_MODULE := libOmxVenc
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(libmm-venc-def)
+LOCAL_C_INCLUDES := $(libmm-venc-inc)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils
+
+LOCAL_SRC_FILES := src/omx_video_base.cpp
+LOCAL_SRC_FILES += src/omx_video_encoder.cpp
+ifeq ($(TARGET_BOARD_PLATFORM),msm8974)
+LOCAL_SRC_FILES += src/video_encoder_device_copper.cpp
+else
+LOCAL_SRC_FILES += src/video_encoder_device.cpp
+endif
+
+
+LOCAL_SRC_FILES += ../common/src/extra_data_handler.cpp
+
+include $(BUILD_SHARED_LIBRARY)
+
+# -----------------------------------------------------------------------------
+# # Make the apps-test (mm-venc-omx-test720p)
+# -----------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+mm-venc-test720p-inc := $(TARGET_OUT_HEADERS)/mm-core
+mm-venc-test720p-inc += $(LOCAL_PATH)/inc
+mm-venc-test720p-inc += $(OMX_VIDEO_PATH)/vidc/common/inc
+mm-venc-test720p-inc += hardware/qcom/media/mm-core/inc
+mm-venc-test720p-inc += hardware/qcom/display/libgralloc
+
+LOCAL_MODULE := mm-venc-omx-test720p
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(libmm-venc-def)
+LOCAL_C_INCLUDES := $(mm-venc-test720p-inc)
+#LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+LOCAL_PRELINK_MODULE := false
+LOCAL_SHARED_LIBRARIES := libmm-omxcore libOmxVenc libbinder
+
+LOCAL_SRC_FILES := test/venc_test.cpp
+LOCAL_SRC_FILES += test/camera_test.cpp
+LOCAL_SRC_FILES += test/venc_util.c
+LOCAL_SRC_FILES += test/fb_test.c
+
+include $(BUILD_EXECUTABLE)
+
+# -----------------------------------------------------------------------------
+# Make the apps-test (mm-video-driver-test)
+# -----------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+venc-test-inc += $(LOCAL_PATH)/inc
+venc-test-inc += hardware/qcom/display/libgralloc
+
+LOCAL_MODULE := mm-video-encdrv-test
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(venc-test-inc)
+LOCAL_C_INCLUDES += hardware/qcom/media/mm-core/inc
+
+#LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_SRC_FILES := test/video_encoder_test.c
+LOCAL_SRC_FILES += test/queue.c
+
+include $(BUILD_EXECUTABLE)
+
+endif #BUILD_TINY_ANDROID
+
+# ---------------------------------------------------------------------------------
+# END
+# ---------------------------------------------------------------------------------
+
diff --git a/mm-video/vidc/venc/inc/camera_test.h b/mm-video/vidc/venc/inc/camera_test.h
new file mode 100755
index 0000000..f206c61
--- /dev/null
+++ b/mm-video/vidc/venc/inc/camera_test.h
@@ -0,0 +1,58 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#ifndef _CAMERA_TEST_H
+#define _CAMERA_TEST_H
+
+#define EXTERN_C_START extern "C" {
+#define EXTERN_C_END }
+
+#ifdef __cplusplus
+EXTERN_C_START
+#endif
+
+typedef void (*CameraPreviewCallback)(int nFD,
+ int nOffset,
+ void* pPhys,
+ void* pVirt,
+ long long nTimeStamp);
+
+
+int CameraTest_Initialize(int nFrameRate,
+ int nFrameWidth,
+ int nFrameHeight,
+ CameraPreviewCallback pfnPreviewCallback);
+int CameraTest_Run();
+int CameraTest_ReleaseFrame(void* pPhys, void* pVirt);
+int CameraTest_Exit();
+
+
+#ifdef __cplusplus
+EXTERN_C_END
+#endif
+
+#endif
diff --git a/mm-video/vidc/venc/inc/fb_test.h b/mm-video/vidc/venc/inc/fb_test.h
new file mode 100755
index 0000000..1ebc76a
--- /dev/null
+++ b/mm-video/vidc/venc/inc/fb_test.h
@@ -0,0 +1,48 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#ifndef _FB_TEST_H
+#define _FB_TEST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int FBTest_Initialize(int nFrameWidth,
+ int nFrameHeight);
+int FBTest_DisplayImage(int nPmemFd, int nOffset);
+int FBTest_Exit();
+
+int FBTest_RunTest();
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // _FB_TEST_H
diff --git a/mm-video/vidc/venc/inc/omx_video_base.h b/mm-video/vidc/venc/inc/omx_video_base.h
new file mode 100755
index 0000000..b7f8ffd
--- /dev/null
+++ b/mm-video/vidc/venc/inc/omx_video_base.h
@@ -0,0 +1,559 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+
+#ifndef __OMX_VIDEO_BASE_H__
+#define __OMX_VIDEO_BASE_H__
+/*============================================================================
+ O p e n M A X Component
+ Video Encoder
+
+*//** @file comx_video_base.h
+ This module contains the class definition for openMAX decoder component.
+
+*//*========================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+
+#include<stdlib.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#ifdef _ANDROID_
+ #include <binder/MemoryHeapBase.h>
+#ifdef _ANDROID_ICS_
+ #include "QComOMXMetadata.h"
+#endif
+#endif // _ANDROID_
+#include <pthread.h>
+#include <semaphore.h>
+#include <linux/msm_vidc_enc.h>
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "qc_omx_component.h"
+#include "omx_video_common.h"
+#include "extra_data_handler.h"
+#include <linux/videodev2.h>
+
+#ifdef _ANDROID_
+using namespace android;
+// local pmem heap object
+class VideoHeap : public MemoryHeapBase
+{
+public:
+ VideoHeap(int fd, size_t size, void* base);
+ virtual ~VideoHeap() {}
+};
+
+#include <utils/Log.h>
+#define LOG_TAG "OMX-VENC-720p"
+#ifdef ENABLE_DEBUG_LOW
+#define DEBUG_PRINT_LOW ALOGV
+#else
+#define DEBUG_PRINT_LOW
+#endif
+#ifdef ENABLE_DEBUG_HIGH
+#define DEBUG_PRINT_HIGH ALOGV
+#else
+#define DEBUG_PRINT_HIGH
+#endif
+#ifdef ENABLE_DEBUG_ERROR
+#define DEBUG_PRINT_ERROR ALOGE
+#else
+#define DEBUG_PRINT_ERROR
+#endif
+
+#else //_ANDROID_
+#define DEBUG_PRINT_LOW
+#define DEBUG_PRINT_HIGH
+#define DEBUG_PRINT_ERROR
+#endif // _ANDROID_
+
+#ifdef USE_ION
+ static const char* MEM_DEVICE = "/dev/ion";
+ #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
+#elif MAX_RES_720P
+static const char* MEM_DEVICE = "/dev/pmem_adsp";
+#elif MAX_RES_1080P_EBI
+static const char* MEM_DEVICE = "/dev/pmem_adsp";
+#elif MAX_RES_1080P
+static const char* MEM_DEVICE = "/dev/pmem_smipool";
+#else
+#error MEM_DEVICE cannot be determined.
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Module specific globals
+//////////////////////////////////////////////////////////////////////////////
+
+#define OMX_SPEC_VERSION 0x00000101
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Macros
+//////////////////////////////////////////////////////////////////////////////
+#define PrintFrameHdr(bufHdr) DEBUG_PRINT("bufHdr %x buf %x size %d TS %d\n",\
+ (unsigned) bufHdr,\
+ (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->pBuffer,\
+ (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nFilledLen,\
+ (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp)
+
+// BitMask Management logic
+#define BITS_PER_BYTE 32
+#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE)
+#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_BYTE)
+#define BITMASK_FLAG(mIndex) (1 << ((mIndex) % BITS_PER_BYTE))
+#define BITMASK_CLEAR(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \
+ &= ~(BITMASK_FLAG(mIndex))
+#define BITMASK_SET(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \
+ |= BITMASK_FLAG(mIndex)
+#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \
+ & BITMASK_FLAG(mIndex))
+#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \
+ & BITMASK_FLAG(mIndex)) == 0x0)
+#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \
+ & BITMASK_FLAG(mIndex))
+#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \
+ & BITMASK_FLAG(mIndex)) == 0x0)
+#ifdef _ANDROID_ICS_
+#define MAX_NUM_INPUT_BUFFERS 32
+#endif
+void* message_thread(void *);
+// OMX video class
+class omx_video: public qc_omx_component
+{
+protected:
+#ifdef _ANDROID_ICS_
+ bool meta_mode_enable;
+ encoder_media_buffer_type meta_buffers[MAX_NUM_INPUT_BUFFERS];
+ OMX_BUFFERHEADERTYPE meta_buffer_hdr[MAX_NUM_INPUT_BUFFERS];
+ bool mUseProxyColorFormat;
+#endif
+public:
+ omx_video(); // constructor
+ virtual ~omx_video(); // destructor
+
+ // virtual int async_message_process (void *context, void* message);
+ void process_event_cb(void *ctxt,unsigned char id);
+
+ OMX_ERRORTYPE allocate_buffer(
+ OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ OMX_U32 bytes
+ );
+
+
+ virtual OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp)= 0;
+
+ virtual OMX_ERRORTYPE component_init(OMX_STRING role)= 0;
+
+ virtual OMX_U32 dev_stop(void) = 0;
+ virtual OMX_U32 dev_pause(void) = 0;
+ virtual OMX_U32 dev_start(void) = 0;
+ virtual OMX_U32 dev_flush(unsigned) = 0;
+ virtual OMX_U32 dev_resume(void) = 0;
+ virtual OMX_U32 dev_start_done(void) = 0;
+ virtual OMX_U32 dev_stop_done(void) = 0;
+ virtual bool dev_use_buf(void *,unsigned,unsigned) = 0;
+ virtual bool dev_free_buf(void *,unsigned) = 0;
+ virtual bool dev_empty_buf(void *, void *,unsigned,unsigned) = 0;
+ virtual bool dev_fill_buf(void *buffer, void *,unsigned,unsigned) = 0;
+ virtual bool dev_get_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32) = 0;
+ virtual bool dev_get_seq_hdr(void *, unsigned, unsigned *) = 0;
+ virtual bool dev_loaded_start(void) = 0;
+ virtual bool dev_loaded_stop(void) = 0;
+ virtual bool dev_loaded_start_done(void) = 0;
+ virtual bool dev_loaded_stop_done(void) = 0;
+#ifdef _ANDROID_ICS_
+ void omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer);
+#endif
+ OMX_ERRORTYPE component_role_enum(
+ OMX_HANDLETYPE hComp,
+ OMX_U8 *role,
+ OMX_U32 index
+ );
+
+ OMX_ERRORTYPE component_tunnel_request(
+ OMX_HANDLETYPE hComp,
+ OMX_U32 port,
+ OMX_HANDLETYPE peerComponent,
+ OMX_U32 peerPort,
+ OMX_TUNNELSETUPTYPE *tunnelSetup
+ );
+
+ OMX_ERRORTYPE empty_this_buffer(
+ OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer
+ );
+
+
+
+ OMX_ERRORTYPE fill_this_buffer(
+ OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer
+ );
+
+
+ OMX_ERRORTYPE free_buffer(
+ OMX_HANDLETYPE hComp,
+ OMX_U32 port,
+ OMX_BUFFERHEADERTYPE *buffer
+ );
+
+ OMX_ERRORTYPE get_component_version(
+ OMX_HANDLETYPE hComp,
+ OMX_STRING componentName,
+ OMX_VERSIONTYPE *componentVersion,
+ OMX_VERSIONTYPE *specVersion,
+ OMX_UUIDTYPE *componentUUID
+ );
+
+ OMX_ERRORTYPE get_config(
+ OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE configIndex,
+ OMX_PTR configData
+ );
+
+ OMX_ERRORTYPE get_extension_index(
+ OMX_HANDLETYPE hComp,
+ OMX_STRING paramName,
+ OMX_INDEXTYPE *indexType
+ );
+
+ OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE paramIndex,
+ OMX_PTR paramData);
+
+ OMX_ERRORTYPE get_state(OMX_HANDLETYPE hComp,
+ OMX_STATETYPE *state);
+
+
+
+ OMX_ERRORTYPE send_command(OMX_HANDLETYPE hComp,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param1,
+ OMX_PTR cmdData);
+
+
+ OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE hComp,
+ OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData);
+
+ virtual OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE configIndex,
+ OMX_PTR configData) = 0;
+
+ virtual OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE paramIndex,
+ OMX_PTR paramData) =0;
+
+ OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ OMX_U32 bytes,
+ OMX_U8 *buffer);
+
+
+ OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ void * eglImage);
+
+
+
+ int m_pipe_in;
+ int m_pipe_out;
+
+ pthread_t msg_thread_id;
+ pthread_t async_thread_id;
+
+ OMX_U8 m_nkind[128];
+
+
+ //int *input_pmem_fd;
+ //int *output_pmem_fd;
+ struct pmem *m_pInput_pmem;
+ struct pmem *m_pOutput_pmem;
+#ifdef USE_ION
+ struct venc_ion *m_pInput_ion;
+ struct venc_ion *m_pOutput_ion;
+#endif
+
+
+
+public:
+ // Bit Positions
+ enum flags_bit_positions
+ {
+ // Defer transition to IDLE
+ OMX_COMPONENT_IDLE_PENDING =0x1,
+ // Defer transition to LOADING
+ OMX_COMPONENT_LOADING_PENDING =0x2,
+ // First Buffer Pending
+ OMX_COMPONENT_FIRST_BUFFER_PENDING =0x3,
+ // Second Buffer Pending
+ OMX_COMPONENT_SECOND_BUFFER_PENDING =0x4,
+ // Defer transition to Enable
+ OMX_COMPONENT_INPUT_ENABLE_PENDING =0x5,
+ // Defer transition to Enable
+ OMX_COMPONENT_OUTPUT_ENABLE_PENDING =0x6,
+ // Defer transition to Disable
+ OMX_COMPONENT_INPUT_DISABLE_PENDING =0x7,
+ // Defer transition to Disable
+ OMX_COMPONENT_OUTPUT_DISABLE_PENDING =0x8,
+ //defer flush notification
+ OMX_COMPONENT_OUTPUT_FLUSH_PENDING =0x9,
+ OMX_COMPONENT_INPUT_FLUSH_PENDING =0xA,
+ OMX_COMPONENT_PAUSE_PENDING =0xB,
+ OMX_COMPONENT_EXECUTE_PENDING =0xC,
+ OMX_COMPONENT_LOADED_START_PENDING = 0xD,
+ OMX_COMPONENT_LOADED_STOP_PENDING = 0xF,
+
+ };
+
+ // Deferred callback identifiers
+ enum
+ {
+ //Event Callbacks from the venc component thread context
+ OMX_COMPONENT_GENERATE_EVENT = 0x1,
+ //Buffer Done callbacks from the venc component thread context
+ OMX_COMPONENT_GENERATE_BUFFER_DONE = 0x2,
+ //Frame Done callbacks from the venc component thread context
+ OMX_COMPONENT_GENERATE_FRAME_DONE = 0x3,
+ //Buffer Done callbacks from the venc component thread context
+ OMX_COMPONENT_GENERATE_FTB = 0x4,
+ //Frame Done callbacks from the venc component thread context
+ OMX_COMPONENT_GENERATE_ETB = 0x5,
+ //Command
+ OMX_COMPONENT_GENERATE_COMMAND = 0x6,
+ //Push-Pending Buffers
+ OMX_COMPONENT_PUSH_PENDING_BUFS = 0x7,
+ // Empty Buffer Done callbacks
+ OMX_COMPONENT_GENERATE_EBD = 0x8,
+ //Flush Event Callbacks from the venc component thread context
+ OMX_COMPONENT_GENERATE_EVENT_FLUSH = 0x9,
+ OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH = 0x0A,
+ OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH = 0x0B,
+ OMX_COMPONENT_GENERATE_FBD = 0xc,
+ OMX_COMPONENT_GENERATE_START_DONE = 0xD,
+ OMX_COMPONENT_GENERATE_PAUSE_DONE = 0xE,
+ OMX_COMPONENT_GENERATE_RESUME_DONE = 0xF,
+ OMX_COMPONENT_GENERATE_STOP_DONE = 0x10,
+ OMX_COMPONENT_GENERATE_HARDWARE_ERROR = 0x11
+ };
+
+ struct omx_event
+ {
+ unsigned param1;
+ unsigned param2;
+ unsigned id;
+ };
+
+ struct omx_cmd_queue
+ {
+ omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE];
+ unsigned m_read;
+ unsigned m_write;
+ unsigned m_size;
+
+ omx_cmd_queue();
+ ~omx_cmd_queue();
+ bool insert_entry(unsigned p1, unsigned p2, unsigned id);
+ bool pop_entry(unsigned *p1,unsigned *p2, unsigned *id);
+ // get msgtype of the first ele from the queue
+ unsigned get_q_msg_type();
+
+ };
+
+ bool allocate_done(void);
+ bool allocate_input_done(void);
+ bool allocate_output_done(void);
+
+ OMX_ERRORTYPE free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr);
+ OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr);
+
+ OMX_ERRORTYPE allocate_input_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ OMX_U32 bytes);
+#ifdef _ANDROID_ICS_
+ OMX_ERRORTYPE allocate_input_meta_buffer(OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_PTR appData,
+ OMX_U32 bytes);
+#endif
+ OMX_ERRORTYPE allocate_output_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,OMX_PTR appData,
+ OMX_U32 bytes);
+
+ OMX_ERRORTYPE use_input_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ OMX_U32 bytes,
+ OMX_U8 *buffer);
+
+ OMX_ERRORTYPE use_output_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ OMX_U32 bytes,
+ OMX_U8 *buffer);
+
+ bool execute_omx_flush(OMX_U32);
+ bool execute_output_flush(void);
+ bool execute_input_flush(void);
+ OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer);
+
+ OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer);
+ OMX_ERRORTYPE empty_this_buffer_proxy(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer);
+ bool release_done();
+
+ bool release_output_done();
+ bool release_input_done();
+
+ OMX_ERRORTYPE send_command_proxy(OMX_HANDLETYPE hComp,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param1,
+ OMX_PTR cmdData);
+ bool post_event( unsigned int p1,
+ unsigned int p2,
+ unsigned int id
+ );
+ OMX_ERRORTYPE get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType);
+ inline void omx_report_error ()
+ {
+ if(m_pCallbacks.EventHandler && !m_error_propogated)
+ {
+ m_error_propogated = true;
+ m_pCallbacks.EventHandler(&m_cmp,m_app_data,
+ OMX_EventError,OMX_ErrorHardware,0,NULL);
+ }
+ }
+
+ void complete_pending_buffer_done_cbs();
+
+ //*************************************************************
+ //*******************MEMBER VARIABLES *************************
+ //*************************************************************
+
+ pthread_mutex_t m_lock;
+ sem_t m_cmd_lock;
+ bool m_error_propogated;
+
+ //sem to handle the minimum procesing of commands
+
+
+ // compression format
+ //OMX_VIDEO_CODINGTYPE eCompressionFormat;
+ // OMX State
+ OMX_STATETYPE m_state;
+ // Application data
+ OMX_PTR m_app_data;
+ OMX_BOOL m_use_input_pmem;
+ OMX_BOOL m_use_output_pmem;
+ // Application callbacks
+ OMX_CALLBACKTYPE m_pCallbacks;
+ OMX_PORT_PARAM_TYPE m_sPortParam;
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE m_sParamProfileLevel;
+ OMX_VIDEO_PARAM_PORTFORMATTYPE m_sInPortFormat;
+ OMX_VIDEO_PARAM_PORTFORMATTYPE m_sOutPortFormat;
+ OMX_PARAM_PORTDEFINITIONTYPE m_sInPortDef;
+ OMX_PARAM_PORTDEFINITIONTYPE m_sOutPortDef;
+ OMX_VIDEO_PARAM_MPEG4TYPE m_sParamMPEG4;
+ OMX_VIDEO_PARAM_H263TYPE m_sParamH263;
+ OMX_VIDEO_PARAM_AVCTYPE m_sParamAVC;
+ OMX_PORT_PARAM_TYPE m_sPortParam_img;
+ OMX_PORT_PARAM_TYPE m_sPortParam_audio;
+ OMX_VIDEO_CONFIG_BITRATETYPE m_sConfigBitrate;
+ OMX_CONFIG_FRAMERATETYPE m_sConfigFramerate;
+ OMX_VIDEO_PARAM_BITRATETYPE m_sParamBitrate;
+ OMX_PRIORITYMGMTTYPE m_sPriorityMgmt;
+ OMX_PARAM_BUFFERSUPPLIERTYPE m_sInBufSupplier;
+ OMX_PARAM_BUFFERSUPPLIERTYPE m_sOutBufSupplier;
+ OMX_CONFIG_ROTATIONTYPE m_sConfigFrameRotation;
+ OMX_CONFIG_INTRAREFRESHVOPTYPE m_sConfigIntraRefreshVOP;
+ OMX_VIDEO_PARAM_QUANTIZATIONTYPE m_sSessionQuantization;
+ OMX_VIDEO_PARAM_AVCSLICEFMO m_sAVCSliceFMO;
+ QOMX_VIDEO_INTRAPERIODTYPE m_sIntraperiod;
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE m_sErrorCorrection;
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE m_sIntraRefresh;
+ OMX_U32 m_sExtraData;
+ OMX_U32 m_sDebugSliceinfo;
+
+ // fill this buffer queue
+ omx_cmd_queue m_ftb_q;
+ // Command Q for rest of the events
+ omx_cmd_queue m_cmd_q;
+ omx_cmd_queue m_etb_q;
+ // Input memory pointer
+ OMX_BUFFERHEADERTYPE *m_inp_mem_ptr;
+ // Output memory pointer
+ OMX_BUFFERHEADERTYPE *m_out_mem_ptr;
+
+ bool input_flush_progress;
+ bool output_flush_progress;
+ bool input_use_buffer;
+ bool output_use_buffer;
+ int pending_input_buffers;
+ int pending_output_buffers;
+
+ unsigned int m_out_bm_count;
+ unsigned int m_inp_bm_count;
+ unsigned int m_flags;
+ unsigned int m_etb_count;
+ unsigned int m_fbd_count;
+#ifdef _ANDROID_
+ // Heap pointer to frame buffers
+ sp<MemoryHeapBase> m_heap_ptr;
+#endif //_ANDROID_
+ // to know whether Event Port Settings change has been triggered or not.
+ bool m_event_port_settings_sent;
+ OMX_U8 m_cRole[OMX_MAX_STRINGNAME_SIZE];
+ extra_data_handler extra_data_handle;
+
+private:
+#ifdef USE_ION
+ int alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data,
+ struct ion_fd_data *fd_data,int flag);
+ void free_ion_memory(struct venc_ion *buf_ion_info);
+#endif
+};
+
+#endif // __OMX_VIDEO_BASE_H__
diff --git a/mm-video/vidc/venc/inc/omx_video_common.h b/mm-video/vidc/venc/inc/omx_video_common.h
new file mode 100755
index 0000000..b57a9fa
--- /dev/null
+++ b/mm-video/vidc/venc/inc/omx_video_common.h
@@ -0,0 +1,85 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+
+#ifndef __OMX_VIDEO_COMMON_H__
+#define __OMX_VIDEO_COMMON_H__
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+
+#include<stdlib.h>
+#include <stdio.h>
+#ifdef USE_ION
+#include <ion_msm.h>
+#endif
+
+#define OMX_VIDEO_DEC_NUM_INPUT_BUFFERS 2
+#define OMX_VIDEO_DEC_NUM_OUTPUT_BUFFERS 2
+
+#ifdef FEATURE_QTV_WVGA_ENABLE
+#define OMX_VIDEO_DEC_INPUT_BUFFER_SIZE (256*1024)
+#else
+#define OMX_VIDEO_DEC_INPUT_BUFFER_SIZE (128*1024)
+#endif
+
+#define OMX_CORE_CONTROL_CMDQ_SIZE 100
+#define OMX_CORE_QCIF_HEIGHT 144
+#define OMX_CORE_QCIF_WIDTH 176
+#define OMX_CORE_VGA_HEIGHT 480
+#define OMX_CORE_VGA_WIDTH 640
+#define OMX_CORE_WVGA_HEIGHT 480
+#define OMX_CORE_WVGA_WIDTH 800
+
+enum PortIndexType
+{
+ PORT_INDEX_IN = 0,
+ PORT_INDEX_OUT = 1,
+ PORT_INDEX_BOTH = -1,
+ PORT_INDEX_NONE = -2
+};
+
+struct pmem
+{
+ void *buffer;
+ int fd;
+ unsigned offset;
+ unsigned size;
+};
+#ifdef USE_ION
+struct venc_ion
+{
+ int ion_device_fd;
+ struct ion_fd_data fd_ion_data;
+ struct ion_allocation_data ion_alloc_data;
+};
+#endif
+#endif // __OMX_VIDEO_COMMON_H__
+
+
+
+
diff --git a/mm-video/vidc/venc/inc/omx_video_encoder.h b/mm-video/vidc/venc/inc/omx_video_encoder.h
new file mode 100755
index 0000000..4404553
--- /dev/null
+++ b/mm-video/vidc/venc/inc/omx_video_encoder.h
@@ -0,0 +1,83 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#ifndef __OMX_VENC__H
+#define __OMX_VENC__H
+
+#include <unistd.h>
+#include "omx_video_base.h"
+#ifdef _COPPER_
+#include "video_encoder_device_copper.h"
+#else
+#include "video_encoder_device.h"
+#endif
+
+extern "C" {
+ OMX_API void * get_omx_component_factory_fn(void);
+}
+
+class omx_venc: public omx_video
+{
+public:
+ omx_venc(); //constructor
+ ~omx_venc(); //des
+ static int async_message_process (void *context, void* message);
+ OMX_ERRORTYPE component_init(OMX_STRING role);
+ OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE paramIndex,
+ OMX_PTR paramData);
+ OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE configIndex,
+ OMX_PTR configData);
+ OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp);
+ //OMX strucutres
+ OMX_U32 m_nVenc_format;
+ class venc_dev *handle;
+
+private:
+ OMX_U32 dev_stop(void);
+ OMX_U32 dev_pause(void);
+ OMX_U32 dev_start(void);
+ OMX_U32 dev_flush(unsigned);
+ OMX_U32 dev_resume(void);
+ OMX_U32 dev_start_done(void);
+ OMX_U32 dev_stop_done(void);
+ bool dev_use_buf( void *,unsigned,unsigned);
+ bool dev_free_buf( void *,unsigned);
+ bool dev_empty_buf(void *, void *,unsigned,unsigned);
+ bool dev_fill_buf(void *, void *,unsigned,unsigned);
+ bool dev_get_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32);
+ bool dev_set_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32);
+ bool update_profile_level();
+ bool dev_get_seq_hdr(void *, unsigned, unsigned *);
+ bool dev_loaded_start(void);
+ bool dev_loaded_stop(void);
+ bool dev_loaded_start_done(void);
+ bool dev_loaded_stop_done(void);
+};
+
+#endif //__OMX_VENC__H
diff --git a/mm-video/vidc/venc/inc/queue.h b/mm-video/vidc/venc/inc/queue.h
new file mode 100755
index 0000000..39c656a
--- /dev/null
+++ b/mm-video/vidc/venc/inc/queue.h
@@ -0,0 +1,80 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#include<pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Message Queue structure */
+struct video_msgq
+{
+ /* Command to be executed */
+ unsigned int cmd;
+
+ unsigned int status;
+
+ /* Client-specific data */
+ void *clientdata;
+};
+
+
+/* Thread & Message Queue information */
+struct video_queue_context
+{
+ /* Message Queue related members */
+ pthread_mutex_t mutex;
+ sem_t sem_message;
+ int commandq_size;
+ int dataq_size;
+ struct video_msgq *ptr_dataq;
+ struct video_msgq *ptr_cmdq;
+ int write_dataq ;
+ int read_dataq;
+ int write_comq ;
+ int read_comq ;
+
+};
+
+int check_if_queue_empty ( unsigned int queuetocheck,void* queuecontext );
+
+struct video_msgq * queue_get_cmd ( void* queuecontext );
+
+
+
+int queue_post_cmdq ( void *queuecontext,
+ struct video_msgq *post_msg
+ );
+
+int queue_post_dataq ( void *queuecontext,
+ struct video_msgq *post_msg
+ );
+
+#endif /* QUEUE_H */
diff --git a/mm-video/vidc/venc/inc/venc_util.h b/mm-video/vidc/venc/inc/venc_util.h
new file mode 100755
index 0000000..1062591
--- /dev/null
+++ b/mm-video/vidc/venc/inc/venc_util.h
@@ -0,0 +1,53 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+/*============================================================================
+ V E N C _ U T I L. H
+
+DESCRIPTION
+
+
+REFERENCES
+
+
+============================================================================*/
+
+#ifndef _VENC_UTIL_H
+#define _VENC_UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+long long GetTimeStamp();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mm-video/vidc/venc/inc/video_encoder_device.h b/mm-video/vidc/venc/inc/video_encoder_device.h
new file mode 100755
index 0000000..25df71f
--- /dev/null
+++ b/mm-video/vidc/venc/inc/video_encoder_device.h
@@ -0,0 +1,161 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#ifndef __OMX_VENC_DEV__
+#define __OMX_VENC_DEV__
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "qc_omx_component.h"
+#include "omx_video_common.h"
+#include <linux/msm_vidc_enc.h>
+#include <pthread.h>
+#include <linux/videodev2.h>
+#include <poll.h>
+#define TIMEOUT 5000
+#define MAX_RECON_BUFFERS 4
+
+void* async_venc_message_thread (void *);
+
+class venc_dev
+{
+public:
+ venc_dev(class omx_venc *venc_class); //constructor
+ ~venc_dev(); //des
+
+ bool venc_open(OMX_U32);
+ void venc_close();
+ unsigned venc_stop(void);
+ unsigned venc_pause(void);
+ unsigned venc_start(void);
+ unsigned venc_flush(unsigned);
+#ifdef _ANDROID_ICS_
+ bool venc_set_meta_mode(bool);
+#endif
+ unsigned venc_resume(void);
+ unsigned venc_start_done(void);
+ unsigned venc_stop_done(void);
+ bool venc_use_buf(void*, unsigned,unsigned);
+ bool venc_free_buf(void*, unsigned);
+ bool venc_empty_buf(void *, void *,unsigned,unsigned);
+ bool venc_fill_buf(void *, void *,unsigned,unsigned);
+
+ bool venc_get_buf_req(unsigned long *,unsigned long *,
+ unsigned long *,unsigned long);
+ bool venc_set_buf_req(unsigned long *,unsigned long *,
+ unsigned long *,unsigned long);
+ bool venc_set_param(void *,OMX_INDEXTYPE);
+ bool venc_set_config(void *configData, OMX_INDEXTYPE index);
+ bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel);
+ bool venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate);
+ bool venc_get_seq_hdr(void *, unsigned, unsigned *);
+ bool venc_loaded_start(void);
+ bool venc_loaded_stop(void);
+ bool venc_loaded_start_done(void);
+ bool venc_loaded_stop_done(void);
+ OMX_U32 m_nDriver_fd;
+ bool m_profile_set;
+ bool m_level_set;
+ pthread_mutex_t loaded_start_stop_mlock;
+ pthread_cond_t loaded_start_stop_cond;
+
+ struct recon_buffer {
+ unsigned char* virtual_address;
+ int pmem_fd;
+ int size;
+ int alignment;
+ int offset;
+#ifdef USE_ION
+ int ion_device_fd;
+ struct ion_allocation_data alloc_data;
+ struct ion_fd_data ion_alloc_fd;
+#endif
+ };
+
+ recon_buffer recon_buff[MAX_RECON_BUFFERS];
+ int recon_buffers_count;
+ bool m_max_allowed_bitrate_check;
+ int m_eProfile;
+ int m_eLevel;
+ int etb_count;
+private:
+ struct venc_basecfg m_sVenc_cfg;
+ struct venc_ratectrlcfg rate_ctrl;
+ struct venc_targetbitrate bitrate;
+ struct venc_intraperiod intra_period;
+ struct venc_profile codec_profile;
+ struct ven_profilelevel profile_level;
+ struct venc_switch set_param;
+ struct venc_voptimingcfg time_inc;
+ struct venc_allocatorproperty m_sInput_buff_property;
+ struct venc_allocatorproperty m_sOutput_buff_property;
+ struct venc_sessionqp session_qp;
+ struct venc_multiclicecfg multislice;
+ struct venc_entropycfg entropy;
+ struct venc_dbcfg dbkfilter;
+ struct venc_intrarefresh intra_refresh;
+ struct venc_headerextension hec;
+ struct venc_voptimingcfg voptimecfg;
+ struct venc_seqheader seqhdr;
+
+ bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel);
+ bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames);
+ bool venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config);
+ bool venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate);
+ bool venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp);
+ bool venc_set_extradata(OMX_U32 extra_data);
+ bool venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config);
+ bool venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh);
+ bool venc_set_color_format(OMX_COLOR_FORMATTYPE color_format);
+ bool venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel);
+ bool venc_set_multislice_cfg(OMX_INDEXTYPE codec, OMX_U32 slicesize);
+ bool venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level);
+ bool venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loop_filter);
+ bool venc_set_intra_refresh (OMX_VIDEO_INTRAREFRESHTYPE intrarefresh, OMX_U32 nMBs);
+ bool venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience);
+ bool venc_set_voptiming_cfg(OMX_U32 nTimeIncRes);
+ void venc_config_print();
+ bool venc_set_slice_delivery_mode(OMX_BOOL enable);
+#ifdef MAX_RES_1080P
+ OMX_U32 pmem_free();
+ OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count);
+ OMX_U32 venc_allocate_recon_buffers();
+ inline int clip2(int x)
+ {
+ x = x -1;
+ x = x | x >> 1;
+ x = x | x >> 2;
+ x = x | x >> 4;
+ x = x | x >> 16;
+ x = x + 1;
+ return x;
+ }
+#endif
+};
+
+#endif
diff --git a/mm-video/vidc/venc/inc/video_encoder_device_copper.h b/mm-video/vidc/venc/inc/video_encoder_device_copper.h
new file mode 100755
index 0000000..0089cce
--- /dev/null
+++ b/mm-video/vidc/venc/inc/video_encoder_device_copper.h
@@ -0,0 +1,288 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#ifndef __OMX_VENC_DEV__
+#define __OMX_VENC_DEV__
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "qc_omx_component.h"
+#include "omx_video_common.h"
+#include "omx_video_base.h"
+#include "omx_video_encoder.h"
+#include <linux/videodev2.h>
+#include <poll.h>
+#define TIMEOUT 5000
+#define MAX_RECON_BUFFERS 4
+
+void* async_venc_message_thread (void *);
+
+struct msm_venc_switch{
+ unsigned char status;
+};
+
+struct msm_venc_allocatorproperty{
+ unsigned long mincount;
+ unsigned long maxcount;
+ unsigned long actualcount;
+ unsigned long datasize;
+ unsigned long suffixsize;
+ unsigned long alignment;
+ unsigned long bufpoolid;
+};
+
+struct msm_venc_basecfg{
+ unsigned long input_width;
+ unsigned long input_height;
+ unsigned long dvs_width;
+ unsigned long dvs_height;
+ unsigned long codectype;
+ unsigned long fps_num;
+ unsigned long fps_den;
+ unsigned long targetbitrate;
+ unsigned long inputformat;
+};
+
+struct msm_venc_profile{
+ unsigned long profile;
+};
+struct msm_venc_profilelevel{
+ unsigned long level;
+};
+
+struct msm_venc_sessionqp{
+ unsigned long iframeqp;
+ unsigned long pframqp;
+ unsigned long bframqp;
+};
+
+struct msm_venc_qprange{
+ unsigned long maxqp;
+ unsigned long minqp;
+};
+struct msm_venc_intraperiod{
+ unsigned long num_pframes;
+ unsigned long num_bframes;
+};
+struct msm_venc_seqheader{
+ unsigned char *hdrbufptr;
+ unsigned long bufsize;
+ unsigned long hdrlen;
+};
+
+struct msm_venc_capability{
+ unsigned long codec_types;
+ unsigned long maxframe_width;
+ unsigned long maxframe_height;
+ unsigned long maxtarget_bitrate;
+ unsigned long maxframe_rate;
+ unsigned long input_formats;
+ unsigned char dvs;
+};
+
+struct msm_venc_entropycfg{
+ unsigned longentropysel;
+ unsigned long cabacmodel;
+};
+
+struct msm_venc_dbcfg{
+ unsigned long db_mode;
+ unsigned long slicealpha_offset;
+ unsigned long slicebeta_offset;
+};
+
+struct msm_venc_intrarefresh{
+ unsigned long irmode;
+ unsigned long mbcount;
+};
+
+struct msm_venc_multiclicecfg{
+ unsigned long mslice_mode;
+ unsigned long mslice_size;
+};
+
+struct msm_venc_bufferflush{
+ unsigned long flush_mode;
+};
+
+struct msm_venc_ratectrlcfg{
+ unsigned long rcmode;
+};
+
+struct msm_venc_voptimingcfg{
+ unsigned long voptime_resolution;
+};
+struct msm_venc_framerate{
+ unsigned long fps_denominator;
+ unsigned long fps_numerator;
+};
+
+struct msm_venc_targetbitrate{
+ unsigned long target_bitrate;
+};
+
+
+struct msm_venc_rotation{
+ unsigned long rotation;
+};
+
+struct msm_venc_timeout{
+ unsigned long millisec;
+};
+
+struct msm_venc_headerextension{
+ unsigned long header_extension;
+};
+
+class venc_dev
+{
+public:
+ venc_dev(class omx_venc *venc_class); //constructor
+ ~venc_dev(); //des
+
+ bool venc_open(OMX_U32);
+ void venc_close();
+ unsigned venc_stop(void);
+ unsigned venc_pause(void);
+ unsigned venc_start(void);
+ unsigned venc_flush(unsigned);
+#ifdef _ANDROID_ICS_
+ bool venc_set_meta_mode(bool);
+#endif
+ unsigned venc_resume(void);
+ unsigned venc_start_done(void);
+ unsigned venc_stop_done(void);
+ bool venc_use_buf(void*, unsigned,unsigned);
+ bool venc_free_buf(void*, unsigned);
+ bool venc_empty_buf(void *, void *,unsigned,unsigned);
+ bool venc_fill_buf(void *, void *,unsigned,unsigned);
+
+ bool venc_get_buf_req(unsigned long *,unsigned long *,
+ unsigned long *,unsigned long);
+ bool venc_set_buf_req(unsigned long *,unsigned long *,
+ unsigned long *,unsigned long);
+ bool venc_set_param(void *,OMX_INDEXTYPE);
+ bool venc_set_config(void *configData, OMX_INDEXTYPE index);
+ bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel);
+ bool venc_get_seq_hdr(void *, unsigned, unsigned *);
+ bool venc_loaded_start(void);
+ bool venc_loaded_stop(void);
+ bool venc_loaded_start_done(void);
+ bool venc_loaded_stop_done(void);
+ OMX_U32 m_nDriver_fd;
+ bool m_profile_set;
+ bool m_level_set;
+ struct recon_buffer {
+ unsigned char* virtual_address;
+ int pmem_fd;
+ int size;
+ int alignment;
+ int offset;
+#ifdef USE_ION
+ int ion_device_fd;
+ struct ion_allocation_data alloc_data;
+ struct ion_fd_data ion_alloc_fd;
+#endif
+ };
+
+ recon_buffer recon_buff[MAX_RECON_BUFFERS];
+ int recon_buffers_count;
+ bool m_max_allowed_bitrate_check;
+ int etb_count;
+ class omx_venc *venc_handle;
+private:
+ struct msm_venc_basecfg m_sVenc_cfg;
+ struct msm_venc_ratectrlcfg rate_ctrl;
+ struct msm_venc_targetbitrate bitrate;
+ struct msm_venc_intraperiod intra_period;
+ struct msm_venc_profile codec_profile;
+ struct msm_venc_profilelevel profile_level;
+ struct msm_venc_switch set_param;
+ struct msm_venc_voptimingcfg time_inc;
+ struct msm_venc_allocatorproperty m_sInput_buff_property;
+ struct msm_venc_allocatorproperty m_sOutput_buff_property;
+ struct msm_venc_sessionqp session_qp;
+ struct msm_venc_multiclicecfg multislice;
+ struct msm_venc_entropycfg entropy;
+ struct msm_venc_dbcfg dbkfilter;
+ struct msm_venc_intrarefresh intra_refresh;
+ struct msm_venc_headerextension hec;
+ struct msm_venc_voptimingcfg voptimecfg;
+
+ bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel);
+ bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames);
+ bool venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config);
+ bool venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate);
+ bool venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp);
+ bool venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config);
+ bool venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh);
+ bool venc_set_color_format(OMX_COLOR_FORMATTYPE color_format);
+ bool venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel);
+ bool venc_set_multislice_cfg(OMX_INDEXTYPE codec, OMX_U32 slicesize);
+ bool venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level);
+ bool venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loop_filter);
+ bool venc_set_intra_refresh (OMX_VIDEO_INTRAREFRESHTYPE intrarefresh, OMX_U32 nMBs);
+ bool venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience);
+ bool venc_set_voptiming_cfg(OMX_U32 nTimeIncRes);
+ void venc_config_print();
+#ifdef MAX_RES_1080P
+ OMX_U32 pmem_free();
+ OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count);
+ OMX_U32 venc_allocate_recon_buffers();
+ inline int clip2(int x)
+ {
+ x = x -1;
+ x = x | x >> 1;
+ x = x | x >> 2;
+ x = x | x >> 4;
+ x = x | x >> 16;
+ x = x + 1;
+ return x;
+ }
+#endif
+};
+
+enum instance_state {
+ MSM_VIDC_CORE_UNINIT_DONE = 0x0001,
+ MSM_VIDC_CORE_INIT,
+ MSM_VIDC_CORE_INIT_DONE,
+ MSM_VIDC_OPEN,
+ MSM_VIDC_OPEN_DONE,
+ MSM_VIDC_LOAD_RESOURCES,
+ MSM_VIDC_LOAD_RESOURCES_DONE,
+ MSM_VIDC_START,
+ MSM_VIDC_START_DONE,
+ MSM_VIDC_STOP,
+ MSM_VIDC_STOP_DONE,
+ MSM_VIDC_RELEASE_RESOURCES,
+ MSM_VIDC_RELEASE_RESOURCES_DONE,
+ MSM_VIDC_CLOSE,
+ MSM_VIDC_CLOSE_DONE,
+ MSM_VIDC_CORE_UNINIT,
+};
+#endif
diff --git a/mm-video/vidc/venc/inc/video_encoder_test.h b/mm-video/vidc/venc/inc/video_encoder_test.h
new file mode 100755
index 0000000..1462db0
--- /dev/null
+++ b/mm-video/vidc/venc/inc/video_encoder_test.h
@@ -0,0 +1,76 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "queue.h"
+#include<fcntl.h>
+#include<sys/ioctl.h>
+#include <sys/mman.h>
+#include <linux/msm_vidc_enc.h>
+#include<pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+
+#define INPUT_BUFFER 0
+#define OUTPUT_BUFFER 1
+
+struct video_encoder_context
+{
+ unsigned long input_width;
+ unsigned long input_height;
+ unsigned long codectype;
+ unsigned long fps_num;
+ unsigned long fps_den;
+ unsigned long targetbitrate;
+ unsigned long inputformat;
+
+ struct venc_allocatorproperty input_buffer;
+ struct venc_allocatorproperty output_buffer;
+ struct venc_bufferpayload **ptr_inputbuffer;
+ struct venc_bufferpayload **ptr_outputbuffer;
+ struct video_queue_context queue_context;
+ int video_driver_fd;
+
+ FILE * inputBufferFile;
+ FILE * outputBufferFile;
+
+ pthread_t videothread_id;
+ pthread_t asyncthread_id;
+ sem_t sem_synchronize;
+};
+
+int init_encoder ( struct video_encoder_context *init_decode );
+int allocate_buffer ( unsigned int buffer_dir,
+ struct video_encoder_context *decode_context
+ );
+int free_buffer ( unsigned int buffer_dir,
+ struct video_encoder_context *decode_context
+ );
+int start_encoding (struct video_encoder_context *decode_context);
+int stop_encoding (struct video_encoder_context *decode_context);
+int deinit_encoder (struct video_encoder_context *init_decode);
diff --git a/mm-video/vidc/venc/src/omx_video_base.cpp b/mm-video/vidc/venc/src/omx_video_base.cpp
new file mode 100755
index 0000000..21d3e33
--- /dev/null
+++ b/mm-video/vidc/venc/src/omx_video_base.cpp
@@ -0,0 +1,4272 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+/*============================================================================
+ O p e n M A X w r a p p e r s
+ O p e n M A X C o r e
+
+*//** @file omx_video_base.cpp
+ This module contains the implementation of the OpenMAX core & component.
+
+*//*========================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+
+#include <string.h>
+#include "omx_video_base.h"
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/prctl.h>
+#ifdef _ANDROID_ICS_
+#include <media/hardware/HardwareAPI.h>
+#include <gralloc_priv.h>
+#endif
+#ifndef _ANDROID_
+#include <glib.h>
+#define strlcpy g_strlcpy
+#endif
+#define H264_SUPPORTED_WIDTH (480)
+#define H264_SUPPORTED_HEIGHT (368)
+
+#define MPEG4_SUPPORTED_WIDTH (480)
+#define MPEG4_SUPPORTED_HEIGHT (368)
+
+#define VC1_SP_MP_START_CODE 0xC5000000
+#define VC1_SP_MP_START_CODE_MASK 0xFF000000
+#define VC1_AP_START_CODE 0x00000100
+#define VC1_AP_START_CODE_MASK 0xFFFFFF00
+#define VC1_STRUCT_C_PROFILE_MASK 0xF0
+#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
+#define VC1_SIMPLE_PROFILE 0
+#define VC1_MAIN_PROFILE 1
+#define VC1_ADVANCE_PROFILE 3
+#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
+#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
+#define VC1_STRUCT_C_LEN 4
+#define VC1_STRUCT_C_POS 8
+#define VC1_STRUCT_A_POS 12
+#define VC1_STRUCT_B_POS 24
+#define VC1_SEQ_LAYER_SIZE 36
+
+typedef struct OMXComponentCapabilityFlagsType
+{
+ ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
+ OMX_BOOL iIsOMXComponentMultiThreaded;
+ OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc;
+ OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc;
+ OMX_BOOL iOMXComponentSupportsMovableInputBuffers;
+ OMX_BOOL iOMXComponentSupportsPartialFrames;
+ OMX_BOOL iOMXComponentUsesNALStartCodes;
+ OMX_BOOL iOMXComponentCanHandleIncompleteFrames;
+ OMX_BOOL iOMXComponentUsesFullAVCFrames;
+
+} OMXComponentCapabilityFlagsType;
+#define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347
+
+#ifdef OUTPUT_BUFFER_LOG
+extern FILE *outputBufferFile1;
+#endif
+
+void* message_thread(void *input)
+{
+ omx_video* omx = reinterpret_cast<omx_video*>(input);
+ unsigned char id;
+ int n;
+
+ DEBUG_PRINT_LOW("omx_venc: message thread start\n");
+ prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0);
+ while(1)
+ {
+ n = read(omx->m_pipe_in, &id, 1);
+ if(0 == n)
+ {
+ break;
+ }
+
+ if(1 == n)
+ {
+ omx->process_event_cb(omx, id);
+ }
+#ifdef QLE_BUILD
+ if(n < 0) break;
+#else
+ if((n < 0) && (errno != EINTR)) break;
+#endif
+ }
+ DEBUG_PRINT_LOW("omx_venc: message thread stop\n");
+ return 0;
+}
+
+void post_message(omx_video *omx, unsigned char id)
+{
+ DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id);
+ write(omx->m_pipe_out, &id, 1);
+}
+
+// omx_cmd_queue destructor
+omx_video::omx_cmd_queue::~omx_cmd_queue()
+{
+ // Nothing to do
+}
+
+// omx cmd queue constructor
+omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
+{
+ memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
+}
+
+// omx cmd queue insert
+bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
+{
+ bool ret = true;
+ if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
+ {
+ m_q[m_write].id = id;
+ m_q[m_write].param1 = p1;
+ m_q[m_write].param2 = p2;
+ m_write++;
+ m_size ++;
+ if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
+ {
+ m_write = 0;
+ }
+ }
+ else
+ {
+ ret = false;
+ DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full\n");
+ }
+ return ret;
+}
+
+// omx cmd queue pop
+bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
+{
+ bool ret = true;
+ if(m_size > 0)
+ {
+ *id = m_q[m_read].id;
+ *p1 = m_q[m_read].param1;
+ *p2 = m_q[m_read].param2;
+ // Move the read pointer ahead
+ ++m_read;
+ --m_size;
+ if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
+ {
+ m_read = 0;
+ }
+ }
+ else
+ {
+ ret = false;
+ }
+ return ret;
+}
+
+// Retrieve the first mesg type in the queue
+unsigned omx_video::omx_cmd_queue::get_q_msg_type()
+{
+ return m_q[m_read].id;
+}
+
+
+
+#ifdef _ANDROID_
+VideoHeap::VideoHeap(int fd, size_t size, void* base)
+{
+ // dup file descriptor, map once, use pmem
+ init(dup(fd), base, size, 0 , MEM_DEVICE);
+}
+#endif // _ANDROID_
+
+/* ======================================================================
+FUNCTION
+ omx_venc::omx_venc
+
+DESCRIPTION
+ Constructor
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+omx_video::omx_video(): m_state(OMX_StateInvalid),
+ m_app_data(NULL),
+ m_inp_mem_ptr(NULL),
+ m_out_mem_ptr(NULL),
+ m_pInput_pmem(NULL),
+ m_pOutput_pmem(NULL),
+#ifdef USE_ION
+ m_pInput_ion(NULL),
+ m_pOutput_ion(NULL),
+#endif
+ pending_input_buffers(0),
+ pending_output_buffers(0),
+ m_out_bm_count(0),
+ m_inp_bm_count(0),
+ m_flags(0),
+ m_event_port_settings_sent(false),
+ output_flush_progress (false),
+ input_flush_progress (false),
+ input_use_buffer (false),
+ output_use_buffer (false),
+ m_use_input_pmem(OMX_FALSE),
+ m_use_output_pmem(OMX_FALSE),
+ m_etb_count(0),
+ m_fbd_count(0),
+ m_error_propogated(false)
+{
+ DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()");
+ memset(&m_cmp,0,sizeof(m_cmp));
+ memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
+
+ pthread_mutex_init(&m_lock, NULL);
+ sem_init(&m_cmd_lock,0,0);
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_venc::~omx_venc
+
+DESCRIPTION
+ Destructor
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+omx_video::~omx_video()
+{
+ DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()");
+ if(m_pipe_in) close(m_pipe_in);
+ if(m_pipe_out) close(m_pipe_out);
+ DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n");
+ pthread_join(msg_thread_id,NULL);
+ DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n");
+ pthread_join(async_thread_id,NULL);
+ pthread_mutex_destroy(&m_lock);
+ sem_destroy(&m_cmd_lock);
+ DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count,
+ m_fbd_count);
+ DEBUG_PRINT_HIGH("omx_video: Destructor exit\n");
+ DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n");
+}
+
+/* ======================================================================
+FUNCTION
+ omx_venc::OMXCntrlProcessMsgCb
+
+DESCRIPTION
+ IL Client callbacks are generated through this routine. The decoder
+ provides the thread context for this routine.
+
+PARAMETERS
+ ctxt -- Context information related to the self.
+ id -- Event identifier. This could be any of the following:
+ 1. Command completion event
+ 2. Buffer done callback event
+ 3. Frame done callback event
+
+RETURN VALUE
+ None.
+
+========================================================================== */
+void omx_video::process_event_cb(void *ctxt, unsigned char id)
+{
+ unsigned p1; // Parameter - 1
+ unsigned p2; // Parameter - 2
+ unsigned ident;
+ unsigned qsize=0; // qsize
+ omx_video *pThis = (omx_video *) ctxt;
+
+ if(!pThis)
+ {
+ DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n");
+ return;
+ }
+
+ // Protect the shared queue data structure
+ do
+ {
+ /*Read the message id's from the queue*/
+
+ pthread_mutex_lock(&pThis->m_lock);
+ qsize = pThis->m_cmd_q.m_size;
+ if(qsize)
+ {
+ pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
+ }
+
+ if(qsize == 0)
+ {
+ qsize = pThis->m_ftb_q.m_size;
+ if(qsize)
+ {
+ pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
+ }
+ }
+
+ if(qsize == 0)
+ {
+ qsize = pThis->m_etb_q.m_size;
+ if(qsize)
+ {
+ pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
+ }
+ }
+
+ pthread_mutex_unlock(&pThis->m_lock);
+
+ /*process message if we have one*/
+ if(qsize > 0)
+ {
+ id = ident;
+ switch(id)
+ {
+ case OMX_COMPONENT_GENERATE_EVENT:
+ if(pThis->m_pCallbacks.EventHandler)
+ {
+ switch(p1)
+ {
+ case OMX_CommandStateSet:
+ pThis->m_state = (OMX_STATETYPE) p2;
+ DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state);
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventCmdComplete, p1, p2, NULL);
+ break;
+
+ case OMX_EventError:
+ DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2);
+ if(p2 == OMX_ErrorHardware)
+ {
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventError,OMX_ErrorHardware,0,NULL);
+ }
+ else
+ {
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventError, p2, NULL, NULL );
+
+ }
+ break;
+
+ case OMX_CommandPortDisable:
+ DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \
+ "state \n", p2);
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventCmdComplete, p1, p2, NULL );
+ break;
+ case OMX_CommandPortEnable:
+ DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \
+ , p2);
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
+ OMX_EventCmdComplete, p1, p2, NULL );
+ break;
+
+ default:
+ DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", p1);
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventCmdComplete, p1, p2, NULL );
+ break;
+
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n");
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_ETB:
+ if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
+ pThis->omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FTB:
+ if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n");
+ pThis->omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_COMMAND:
+ pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
+ (OMX_U32)p2,(OMX_PTR)NULL);
+ break;
+
+ case OMX_COMPONENT_GENERATE_EBD:
+ if( pThis->empty_buffer_done(&pThis->m_cmp,
+ (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
+ pThis->omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FBD:
+ if( pThis->fill_buffer_done(&pThis->m_cmp,
+ (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
+ {
+ DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
+ pThis->omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
+
+ pThis->input_flush_progress = false;
+ DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count);
+ m_etb_count = 0;
+ if(pThis->m_pCallbacks.EventHandler)
+ {
+ /*Check if we need generate event for Flush done*/
+ if(BITMASK_PRESENT(&pThis->m_flags,
+ OMX_COMPONENT_INPUT_FLUSH_PENDING))
+ {
+ BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventCmdComplete,OMX_CommandFlush,
+ PORT_INDEX_IN,NULL );
+ }
+ else if(BITMASK_PRESENT(&pThis->m_flags,
+ OMX_COMPONENT_IDLE_PENDING))
+ {
+ if(!pThis->output_flush_progress)
+ {
+ DEBUG_PRINT_LOW("\n dev_stop called after input flush complete\n");
+ if(dev_stop() != 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n");
+ pThis->omx_report_error ();
+ }
+ }
+ }
+ }
+
+ break;
+
+ case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
+
+ pThis->output_flush_progress = false;
+ DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count);
+ m_fbd_count = 0;
+ if(pThis->m_pCallbacks.EventHandler)
+ {
+ /*Check if we need generate event for Flush done*/
+ if(BITMASK_PRESENT(&pThis->m_flags,
+ OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
+ {
+ BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
+
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventCmdComplete,OMX_CommandFlush,
+ PORT_INDEX_OUT,NULL );
+ }
+ else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
+ {
+ DEBUG_PRINT_LOW("\n dev_stop called after Output flush complete\n");
+ if(!pThis->input_flush_progress)
+ {
+ if(dev_stop() != 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n");
+ pThis->omx_report_error ();
+ }
+ }
+ }
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_START_DONE:
+ DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg");
+
+ if(pThis->m_pCallbacks.EventHandler)
+ {
+ DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
+ if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
+ {
+ DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \
+ executing");
+ // Send the callback now
+ BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
+ pThis->m_state = OMX_StateExecuting;
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventCmdComplete,OMX_CommandStateSet,
+ OMX_StateExecuting, NULL);
+ }
+ else if(BITMASK_PRESENT(&pThis->m_flags,
+ OMX_COMPONENT_PAUSE_PENDING))
+ {
+ if(dev_pause())
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n");
+ pThis->omx_report_error ();
+ }
+ }
+ else if (BITMASK_PRESENT(&pThis->m_flags,
+ OMX_COMPONENT_LOADED_START_PENDING))
+ {
+ if(dev_loaded_start_done())
+ {
+ DEBUG_PRINT_LOW("successful loaded Start Done!");
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!");
+ pThis->omx_report_error ();
+ }
+ BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_PAUSE_DONE:
+ DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg");
+ if(pThis->m_pCallbacks.EventHandler)
+ {
+ if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
+ {
+ //Send the callback now
+ pThis->complete_pending_buffer_done_cbs();
+ DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD\n");
+ BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
+ pThis->m_state = OMX_StatePause;
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventCmdComplete,OMX_CommandStateSet,
+ OMX_StatePause, NULL);
+ }
+ }
+
+ break;
+
+ case OMX_COMPONENT_GENERATE_RESUME_DONE:
+ DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg");
+ if(pThis->m_pCallbacks.EventHandler)
+ {
+ if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
+ {
+ // Send the callback now
+ BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
+ pThis->m_state = OMX_StateExecuting;
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventCmdComplete,OMX_CommandStateSet,
+ OMX_StateExecuting,NULL);
+ }
+ }
+
+ break;
+
+ case OMX_COMPONENT_GENERATE_STOP_DONE:
+ DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg");
+ if(pThis->m_pCallbacks.EventHandler)
+ {
+ pThis->complete_pending_buffer_done_cbs();
+ if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
+ {
+ // Send the callback now
+ BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
+ pThis->m_state = OMX_StateIdle;
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data,
+ OMX_EventCmdComplete,OMX_CommandStateSet,
+ OMX_StateIdle,NULL);
+ }
+ else if (BITMASK_PRESENT(&pThis->m_flags,
+ OMX_COMPONENT_LOADED_STOP_PENDING))
+ {
+ if(dev_loaded_stop_done())
+ {
+ DEBUG_PRINT_LOW("successful loaded Stop Done!");
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!");
+ pThis->omx_report_error ();
+ }
+ BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
+ }
+ }
+
+ break;
+
+ case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
+ DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n");
+ pThis->omx_report_error ();
+ break;
+
+ default:
+ DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id);
+ break;
+ }
+ }
+
+ pthread_mutex_lock(&pThis->m_lock);
+ qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
+ pThis->m_etb_q.m_size;
+
+ pthread_mutex_unlock(&pThis->m_lock);
+
+ }
+ while(qsize>0);
+ DEBUG_PRINT_LOW("\n exited the while loop\n");
+
+}
+
+
+
+
+/* ======================================================================
+FUNCTION
+ omx_venc::GetComponentVersion
+
+DESCRIPTION
+ Returns the component version.
+
+PARAMETERS
+ TBD.
+
+RETURN VALUE
+ OMX_ErrorNone.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::get_component_version
+(
+OMX_IN OMX_HANDLETYPE hComp,
+OMX_OUT OMX_STRING componentName,
+OMX_OUT OMX_VERSIONTYPE* componentVersion,
+OMX_OUT OMX_VERSIONTYPE* specVersion,
+OMX_OUT OMX_UUIDTYPE* componentUUID
+)
+{
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ /* TBD -- Return the proper version */
+ if (specVersion)
+ {
+ specVersion->nVersion = OMX_SPEC_VERSION;
+ }
+ return OMX_ErrorNone;
+}
+/* ======================================================================
+FUNCTION
+ omx_venc::SendCommand
+
+DESCRIPTION
+ Returns zero if all the buffers released..
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_COMMANDTYPE cmd,
+ OMX_IN OMX_U32 param1,
+ OMX_IN OMX_PTR cmdData
+ )
+{
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+
+ if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable)
+ {
+ if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH))
+ {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n");
+ return OMX_ErrorBadPortIndex;
+ }
+ }
+ if(cmd == OMX_CommandMarkBuffer)
+ {
+ if(param1 != PORT_INDEX_IN)
+ {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n");
+ return OMX_ErrorBadPortIndex;
+ }
+ if(!cmdData)
+ {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
+ return OMX_ErrorBadParameter;
+ }
+ }
+
+ post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
+ sem_wait(&m_cmd_lock);
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_venc::SendCommand
+
+DESCRIPTION
+ Returns zero if all the buffers released..
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_COMMANDTYPE cmd,
+ OMX_IN OMX_U32 param1,
+ OMX_IN OMX_PTR cmdData
+ )
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ OMX_STATETYPE eState = (OMX_STATETYPE) param1;
+ int bFlag = 1;
+
+ if(cmd == OMX_CommandStateSet)
+ {
+ /***************************/
+ /* Current State is Loaded */
+ /***************************/
+ if(m_state == OMX_StateLoaded)
+ {
+ if(eState == OMX_StateIdle)
+ {
+ //if all buffers are allocated or all ports disabled
+ if(allocate_done() ||
+ ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE))
+ {
+ DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n");
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n");
+ BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
+ // Skip the event notification
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Loaded to Loaded */
+ else if(eState == OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded\n");
+ post_event(OMX_EventError,OMX_ErrorSameState,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorSameState;
+ }
+ /* Requesting transition from Loaded to WaitForResources */
+ else if(eState == OMX_StateWaitForResources)
+ {
+ /* Since error is None , we will post an event
+ at the end of this function definition */
+ DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n");
+ }
+ /* Requesting transition from Loaded to Executing */
+ else if(eState == OMX_StateExecuting)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n");
+ post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+ /* Requesting transition from Loaded to Pause */
+ else if(eState == OMX_StatePause)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n");
+ post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+ /* Requesting transition from Loaded to Invalid */
+ else if(eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\
+ eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+
+ /***************************/
+ /* Current State is IDLE */
+ /***************************/
+ else if(m_state == OMX_StateIdle)
+ {
+ if(eState == OMX_StateLoaded)
+ {
+ if(release_done())
+ {
+ /*
+ Since error is None , we will post an event at the end
+ of this function definition
+ */
+ DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n");
+ if(dev_stop() != 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded");
+ eRet = OMX_ErrorHardware;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n");
+ BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
+ // Skip the event notification
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Idle to Executing */
+ else if(eState == OMX_StateExecuting)
+ {
+ if( dev_start() )
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n");
+ omx_report_error ();
+ eRet = OMX_ErrorHardware;
+ }
+ else
+ {
+ BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
+ DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
+ bFlag = 0;
+ }
+
+ dev_start_done();
+ }
+ /* Requesting transition from Idle to Idle */
+ else if(eState == OMX_StateIdle)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n");
+ post_event(OMX_EventError,OMX_ErrorSameState,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorSameState;
+ }
+ /* Requesting transition from Idle to WaitForResources */
+ else if(eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n");
+ post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+ /* Requesting transition from Idle to Pause */
+ else if(eState == OMX_StatePause)
+ {
+ /*To pause the Video core we need to start the driver*/
+ if( dev_start() )
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n");
+ omx_report_error ();
+ eRet = OMX_ErrorHardware;
+ }
+ else
+ {
+ BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
+ DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n");
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Idle to Invalid */
+ else if(eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+
+ /******************************/
+ /* Current State is Executing */
+ /******************************/
+ else if(m_state == OMX_StateExecuting)
+ {
+ /* Requesting transition from Executing to Idle */
+ if(eState == OMX_StateIdle)
+ {
+ /* Since error is None , we will post an event
+ at the end of this function definition
+ */
+ DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n");
+ //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle
+ BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
+ execute_omx_flush(OMX_ALL);
+ bFlag = 0;
+ dev_stop_done();
+ }
+ /* Requesting transition from Executing to Paused */
+ else if(eState == OMX_StatePause)
+ {
+
+ if(dev_pause())
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n");
+ post_event(OMX_EventError,OMX_ErrorHardware,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorHardware;
+ }
+ else
+ {
+ BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
+ DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause\n");
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Executing to Loaded */
+ else if(eState == OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n");
+ post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+ /* Requesting transition from Executing to WaitForResources */
+ else if(eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n");
+ post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+ /* Requesting transition from Executing to Executing */
+ else if(eState == OMX_StateExecuting)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n");
+ post_event(OMX_EventError,OMX_ErrorSameState,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorSameState;
+ }
+ /* Requesting transition from Executing to Invalid */
+ else if(eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ /***************************/
+ /* Current State is Pause */
+ /***************************/
+ else if(m_state == OMX_StatePause)
+ {
+ /* Requesting transition from Pause to Executing */
+ if(eState == OMX_StateExecuting)
+ {
+ DEBUG_PRINT_LOW("\n Pause --> Executing \n");
+ if( dev_resume() )
+ {
+ post_event(OMX_EventError,OMX_ErrorHardware,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorHardware;
+ }
+ else
+ {
+ BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
+ DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing\n");
+ post_event (NULL, NULL, OMX_COMPONENT_GENERATE_RESUME_DONE);
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Pause to Idle */
+ else if(eState == OMX_StateIdle)
+ {
+ /* Since error is None , we will post an event
+ at the end of this function definition */
+ DEBUG_PRINT_LOW("\n Pause --> Idle \n");
+ BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
+ execute_omx_flush(OMX_ALL);
+ bFlag = 0;
+ }
+ /* Requesting transition from Pause to loaded */
+ else if(eState == OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n");
+ post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+ /* Requesting transition from Pause to WaitForResources */
+ else if(eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n");
+ post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+ /* Requesting transition from Pause to Pause */
+ else if(eState == OMX_StatePause)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n");
+ post_event(OMX_EventError,OMX_ErrorSameState,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorSameState;
+ }
+ /* Requesting transition from Pause to Invalid */
+ else if(eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ /***************************/
+ /* Current State is WaitForResources */
+ /***************************/
+ else if(m_state == OMX_StateWaitForResources)
+ {
+ /* Requesting transition from WaitForResources to Loaded */
+ if(eState == OMX_StateLoaded)
+ {
+ /* Since error is None , we will post an event
+ at the end of this function definition */
+ DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n");
+ }
+ /* Requesting transition from WaitForResources to WaitForResources */
+ else if(eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n");
+ post_event(OMX_EventError,OMX_ErrorSameState,
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorSameState;
+ }
+ /* Requesting transition from WaitForResources to Executing */
+ else if(eState == OMX_StateExecuting)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n");
+ post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+ /* Requesting transition from WaitForResources to Pause */
+ else if(eState == OMX_StatePause)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n");
+ post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+ /* Requesting transition from WaitForResources to Invalid */
+ else if(eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ /* Requesting transition from WaitForResources to Loaded -
+ is NOT tested by Khronos TS */
+
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ /********************************/
+ /* Current State is Invalid */
+ /*******************************/
+ else if(m_state == OMX_StateInvalid)
+ {
+ /* State Transition from Inavlid to any state */
+ if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
+ || OMX_StateIdle || OMX_StateExecuting
+ || OMX_StatePause || OMX_StateInvalid))
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n");
+ post_event(OMX_EventError,OMX_ErrorInvalidState,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ }
+ else if(cmd == OMX_CommandFlush)
+ {
+ if(0 == param1 || OMX_ALL == param1)
+ {
+ BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
+ }
+ if(1 == param1 || OMX_ALL == param1)
+ {
+ //generate output flush event only.
+ BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
+ }
+
+ execute_omx_flush(param1);
+ bFlag = 0;
+ }
+ else if( cmd == OMX_CommandPortEnable)
+ {
+ if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
+ {
+ m_sInPortDef.bEnabled = OMX_TRUE;
+
+ if( (m_state == OMX_StateLoaded &&
+ !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ || allocate_input_done())
+ {
+ post_event(OMX_CommandPortEnable,PORT_INDEX_IN,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
+ BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
+ // Skip the event notification
+ bFlag = 0;
+ }
+ }
+ if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
+ {
+ m_sOutPortDef.bEnabled = OMX_TRUE;
+
+ if( (m_state == OMX_StateLoaded &&
+ !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ || (allocate_output_done()))
+ {
+ post_event(OMX_CommandPortEnable,PORT_INDEX_OUT,
+ OMX_COMPONENT_GENERATE_EVENT);
+
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
+ BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
+ // Skip the event notification
+ bFlag = 0;
+ }
+ }
+ }
+ else if(cmd == OMX_CommandPortDisable)
+ {
+ if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
+ {
+ m_sInPortDef.bEnabled = OMX_FALSE;
+ if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
+ && release_input_done())
+ {
+ post_event(OMX_CommandPortDisable,PORT_INDEX_IN,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ else
+ {
+ BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
+ if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
+ {
+ execute_omx_flush(PORT_INDEX_IN);
+ }
+
+ // Skip the event notification
+ bFlag = 0;
+ }
+ }
+ if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
+ {
+ m_sOutPortDef.bEnabled = OMX_FALSE;
+
+ if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
+ && release_output_done())
+ {
+ post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ else
+ {
+ BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
+ if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
+ {
+ execute_omx_flush(PORT_INDEX_OUT);
+ }
+ // Skip the event notification
+ bFlag = 0;
+
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd);
+ eRet = OMX_ErrorNotImplemented;
+ }
+ if(eRet == OMX_ErrorNone && bFlag)
+ {
+ post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
+ }
+ sem_post(&m_cmd_lock);
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_venc::ExecuteOmxFlush
+
+DESCRIPTION
+ Executes the OMX flush.
+
+PARAMETERS
+ flushtype - input flush(1)/output flush(0)/ both.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_video::execute_omx_flush(OMX_U32 flushType)
+{
+ bool bRet = false;
+ DEBUG_PRINT_LOW("\n execute_omx_flush - %d\n", flushType);
+ if(flushType == 0 || flushType == OMX_ALL)
+ {
+ input_flush_progress = true;
+ //flush input only
+ bRet = execute_input_flush();
+ }
+ if(flushType == 1 || flushType == OMX_ALL)
+ {
+ //flush output only
+ output_flush_progress = true;
+ bRet = execute_output_flush();
+ }
+ return bRet;
+}
+/*=========================================================================
+FUNCTION : execute_output_flush
+
+DESCRIPTION
+ Executes the OMX flush at OUTPUT PORT.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+==========================================================================*/
+bool omx_video::execute_output_flush(void)
+{
+ unsigned p1 = 0; // Parameter - 1
+ unsigned p2 = 0; // Parameter - 2
+ unsigned ident = 0;
+ bool bRet = true;
+
+ /*Generate FBD for all Buffers in the FTBq*/
+ DEBUG_PRINT_LOW("\n execute_output_flush\n");
+ pthread_mutex_lock(&m_lock);
+ while(m_ftb_q.m_size)
+ {
+ m_ftb_q.pop_entry(&p1,&p2,&ident);
+
+ if(ident == OMX_COMPONENT_GENERATE_FTB )
+ {
+ pending_output_buffers++;
+ fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
+ }
+ else if(ident == OMX_COMPONENT_GENERATE_FBD)
+ {
+ fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
+ }
+ }
+
+ pthread_mutex_unlock(&m_lock);
+ /*Check if there are buffers with the Driver*/
+ if(dev_flush(PORT_INDEX_OUT))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed");
+ return false;
+ }
+
+ return bRet;
+}
+/*=========================================================================
+FUNCTION : execute_input_flush
+
+DESCRIPTION
+ Executes the OMX flush at INPUT PORT.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+==========================================================================*/
+bool omx_video::execute_input_flush(void)
+{
+ unsigned p1 = 0; // Parameter - 1
+ unsigned p2 = 0; // Parameter - 2
+ unsigned ident = 0;
+ bool bRet = true;
+
+ /*Generate EBD for all Buffers in the ETBq*/
+ DEBUG_PRINT_LOW("\n execute_input_flush\n");
+
+ pthread_mutex_lock(&m_lock);
+ while(m_etb_q.m_size)
+ {
+ m_etb_q.pop_entry(&p1,&p2,&ident);
+ if(ident == OMX_COMPONENT_GENERATE_ETB)
+ {
+ pending_input_buffers++;
+ empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
+ }
+ else if(ident == OMX_COMPONENT_GENERATE_EBD)
+ {
+ empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
+ }
+ }
+
+ pthread_mutex_unlock(&m_lock);
+ /*Check if there are buffers with the Driver*/
+ if(dev_flush(PORT_INDEX_IN))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed");
+ return false;
+ }
+
+ return bRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_venc::SendCommandEvent
+
+DESCRIPTION
+ Send the event to decoder pipe. This is needed to generate the callbacks
+ in decoder thread context.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_video::post_event(unsigned int p1,
+ unsigned int p2,
+ unsigned int id)
+{
+ bool bRet = false;
+
+
+ pthread_mutex_lock(&m_lock);
+
+ if( id == OMX_COMPONENT_GENERATE_FTB || \
+ (id == OMX_COMPONENT_GENERATE_FRAME_DONE))
+ {
+ m_ftb_q.insert_entry(p1,p2,id);
+ }
+ else if((id == OMX_COMPONENT_GENERATE_ETB) \
+ || (id == OMX_COMPONENT_GENERATE_EBD))
+ {
+ m_etb_q.insert_entry(p1,p2,id);
+ }
+ else
+ {
+ m_cmd_q.insert_entry(p1,p2,id);
+ }
+
+ bRet = true;
+ DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
+ post_message(this, id);
+ pthread_mutex_unlock(&m_lock);
+
+ return bRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_venc::GetParameter
+
+DESCRIPTION
+ OMX Get Parameter method implementation
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ Error None if successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_INOUT OMX_PTR paramData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned int height=0,width = 0;
+
+ DEBUG_PRINT_LOW("get_parameter: \n");
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ if(paramData == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n");
+ return OMX_ErrorBadParameter;
+ }
+ switch(paramIndex)
+ {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
+ if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN)
+ {
+ DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d",
+ m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin,
+ m_sInPortDef.nBufferCountActual);
+ memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
+#ifdef _ANDROID_ICS_
+ if(meta_mode_enable)
+ {
+ portDefn->nBufferSize = sizeof(encoder_media_buffer_type);
+ }
+
+ if (mUseProxyColorFormat) {
+ portDefn->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
+ }
+#endif
+ }
+ else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ m_sOutPortDef.nPortIndex);
+ DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d",
+ m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin,
+ m_sOutPortDef.nBufferCountActual);
+ memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef));
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_IndexParamVideoInit:
+ {
+ OMX_PORT_PARAM_TYPE *portParamType =
+ (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
+
+ memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
+ break;
+ }
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
+
+ if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
+ {
+ int index = portFmt->nIndex;
+ memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
+
+#ifdef _ANDROID_ICS_
+ if (index == 1) {
+ //we support two formats
+ //index 0 - YUV420SP
+ //index 1 - opaque which internally maps to YUV420SP.
+ //this can be extended in the future
+ portFmt->nIndex = index; //restore index set from client
+ portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
+ }
+#endif
+ }
+ else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat));
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_IndexParamVideoBitrate:
+ {
+ OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n");
+
+ if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate));
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4:
+ {
+ OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n");
+ memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
+ break;
+ }
+ case OMX_IndexParamVideoH263:
+ {
+ OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n");
+ memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
+ break;
+ }
+ case OMX_IndexParamVideoAvc:
+ {
+ OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n");
+ memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelQuerySupported:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n");
+ eRet = get_supported_profile_level(pParam);
+ if(eRet)
+ DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %d, %d",
+ pParam->eProfile, pParam->eLevel);
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n");
+ memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
+ break;
+ }
+ /*Component should support this port definition*/
+ case OMX_IndexParamAudioInit:
+ {
+ OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
+ memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
+ break;
+ }
+ /*Component should support this port definition*/
+ case OMX_IndexParamImageInit:
+ {
+ OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
+ memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img));
+ break;
+
+ }
+ /*Component should support this port definition*/
+ case OMX_IndexParamOtherInit:
+ {
+ DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex);
+ eRet =OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ case OMX_IndexParamStandardComponentRole:
+ {
+ OMX_PARAM_COMPONENTROLETYPE *comp_role;
+ comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
+ comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
+ comp_role->nSize = sizeof(*comp_role);
+
+ DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex);
+ if(NULL != comp_role->cRole)
+ {
+ strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex);
+ eRet =OMX_ErrorBadParameter;
+ }
+ break;
+ }
+ /* Added for parameter test */
+ case OMX_IndexParamPriorityMgmt:
+ {
+
+ OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
+ memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt));
+ break;
+ }
+ /* Added for parameter test */
+ case OMX_IndexParamCompBufferSupplier:
+ {
+ OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
+ if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN)
+ {
+ memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier));
+ }
+ else if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT)
+ {
+ memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier));
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_IndexParamVideoQuantization:
+ {
+ OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n");
+ memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization));
+ break;
+ }
+
+ case OMX_IndexParamVideoErrorCorrection:
+ {
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
+ DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n");
+ errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC;
+ errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync;
+ errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing;
+ break;
+ }
+ case OMX_IndexParamVideoIntraRefresh:
+ {
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
+ DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh\n");
+ DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET\n");
+ intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode;
+ intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs;
+ break;
+ }
+ case OMX_QcomIndexPortDefn:
+ //TODO
+ break;
+ case OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
+ {
+ OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData);
+ DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n");
+ pParam->iIsOMXComponentMultiThreaded = OMX_TRUE;
+ pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE;
+ pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
+ pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
+ pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE;
+ pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE;
+ pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE;
+ pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE;
+ m_use_input_pmem = OMX_TRUE;
+ DEBUG_PRINT_LOW("Supporting capability index in encoder node");
+ break;
+ }
+#ifndef MAX_RES_720P
+ case OMX_QcomIndexParamIndexExtraDataType:
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType");
+ QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
+ if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo)
+ {
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ pParam->bEnabled =
+ (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_SLICEINFO) ? 1 : 0);
+ DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: slice information is "
+ "valid for output port only");
+ eRet =OMX_ErrorUnsupportedIndex;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: unsupported index (%x), "
+ "only slice information extradata is supported", pParam->nIndex);
+ eRet =OMX_ErrorUnsupportedIndex;
+ }
+ break;
+ }
+#endif
+ case QOMX_IndexParamVideoSyntaxHdr:
+ {
+ DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr");
+ QOMX_EXTNINDEX_PARAMTYPE* pParam =
+ reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData);
+ BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
+ if(dev_loaded_start())
+ {
+ DEBUG_PRINT_LOW("device start successful");
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("device start failed");
+ BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
+ return OMX_ErrorHardware;
+ }
+ if(dev_get_seq_hdr(pParam->pData,
+ (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)),
+ (unsigned *)&pParam->nDataSize))
+ {
+ DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %d)",
+ pParam->nDataSize);
+ for (unsigned i = 0; i < pParam->nDataSize; i++) {
+ DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i));
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()");
+ eRet = OMX_ErrorHardware;
+ }
+ BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
+ if(dev_loaded_stop())
+ {
+ DEBUG_PRINT_LOW("device stop successful");
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("device stop failed");
+ BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
+ eRet = OMX_ErrorHardware;
+ }
+ break;
+ }
+ case OMX_IndexParamVideoSliceFMO:
+ default:
+ {
+ DEBUG_PRINT_ERROR("ERROR: get_parameter: unknown param %08x\n", paramIndex);
+ eRet =OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ }
+
+ return eRet;
+
+}
+/* ======================================================================
+FUNCTION
+ omx_video::GetConfig
+
+DESCRIPTION
+ OMX Get Config Method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_INOUT OMX_PTR configData)
+{
+ ////////////////////////////////////////////////////////////////
+ // Supported Config Index Type
+ // =============================================================
+ // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE
+ // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE
+ // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE
+ ////////////////////////////////////////////////////////////////
+
+ if(configData == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR: param is null");
+ return OMX_ErrorBadParameter;
+ }
+
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: can't be in invalid state");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ //@todo need to validate params
+ switch(configIndex)
+ {
+ case OMX_IndexConfigVideoBitrate:
+ {
+ OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
+ memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
+ memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
+ break;
+ }
+ case OMX_IndexConfigCommonRotate:
+ {
+ OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
+ memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation));
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod\n");
+ QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
+ memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod));
+ break;
+ }
+ default:
+ DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
+ return OMX_ErrorUnsupportedIndex;
+ }
+ return OMX_ErrorNone;
+
+}
+
+/* ======================================================================
+FUNCTION
+ omx_video::GetExtensionIndex
+
+DESCRIPTION
+ OMX GetExtensionIndex method implementaion. <TBD>
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_STRING paramName,
+ OMX_OUT OMX_INDEXTYPE* indexType)
+{
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+#ifdef MAX_RES_1080P
+ if (!strncmp(paramName, "OMX.QCOM.index.param.SliceDeliveryMode",
+ sizeof("OMX.QCOM.index.param.SliceDeliveryMode") - 1)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode;
+ return OMX_ErrorNone;
+ }
+#endif
+#ifdef _ANDROID_ICS_
+ if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers",sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoEncodeMetaBufferMode;
+ return OMX_ErrorNone;
+ }
+#endif
+ return OMX_ErrorNotImplemented;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_video::GetState
+
+DESCRIPTION
+ Returns the state information back to the caller.<TBD>
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ Error None if everything is successful.
+========================================================================== */
+OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_STATETYPE* state)
+{
+ *state = m_state;
+ DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_video::ComponentTunnelRequest
+
+DESCRIPTION
+ OMX Component Tunnel Request method implementation. <TBD>
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_HANDLETYPE peerComponent,
+ OMX_IN OMX_U32 peerPort,
+ OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
+{
+ DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n");
+ return OMX_ErrorNotImplemented;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_video::UseInputBuffer
+
+DESCRIPTION
+ Helper function for Use buffer in the input pin
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::use_input_buffer(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes,
+ OMX_IN OMX_U8* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ unsigned i = 0;
+ unsigned char *buf_addr = NULL;
+
+ DEBUG_PRINT_HIGH("use_input_buffer: port = %d appData = %p bytes = %d buffer = %p",port,appData,bytes,buffer);
+ if(bytes != m_sInPortDef.nBufferSize)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! "
+ "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sInPortDef.nBufferSize);
+ return OMX_ErrorBadParameter;
+ }
+
+ if(!m_inp_mem_ptr)
+ {
+ input_use_buffer = true;
+ m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
+ calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
+ if(m_inp_mem_ptr == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr");
+ return OMX_ErrorInsufficientResources;
+ }
+
+
+ m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
+ if(m_pInput_pmem == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem");
+ return OMX_ErrorInsufficientResources;
+ }
+#ifdef USE_ION
+ m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
+ if(m_pInput_ion == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+
+ for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
+ {
+ m_pInput_pmem[i].fd = -1;
+#ifdef USE_ION
+ m_pInput_ion[i].ion_device_fd =-1;
+ m_pInput_ion[i].fd_ion_data.fd =-1;
+ m_pInput_ion[i].ion_alloc_data.handle=NULL;
+#endif
+ }
+
+ }
+
+ for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
+ {
+ if(BITMASK_ABSENT(&m_inp_bm_count,i))
+ {
+ break;
+ }
+ }
+
+ if(i < m_sInPortDef.nBufferCountActual)
+ {
+
+ *bufferHdr = (m_inp_mem_ptr + i);
+ BITMASK_SET(&m_inp_bm_count,i);
+
+ (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
+ (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
+ (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize;
+ (*bufferHdr)->pAppPrivate = appData;
+ (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN;
+
+ if(!m_use_input_pmem)
+ {
+#ifdef USE_ION
+ m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
+ &m_pInput_ion[i].ion_alloc_data,
+ &m_pInput_ion[i].fd_ion_data,CACHED);
+ if(m_pInput_ion[i].ion_device_fd < 0) {
+ DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
+ return OMX_ErrorInsufficientResources;
+ }
+ m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
+#else
+ m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
+ if(m_pInput_pmem[i].fd == 0)
+ {
+ m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
+ }
+
+ if(m_pInput_pmem[i] .fd < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
+ m_pInput_pmem[i].offset = 0;
+ m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
+ MAP_SHARED,m_pInput_pmem[i].fd,0);
+
+ if(m_pInput_pmem[i].buffer == MAP_FAILED)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: mmap() Failed");
+ close(m_pInput_pmem[i].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pInput_ion[i]);
+#endif
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else
+ {
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate);
+ DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset);
+
+ if(pParam)
+ {
+ m_pInput_pmem[i].fd = pParam->pmem_fd;
+ m_pInput_pmem[i].offset = pParam->offset;
+ m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
+ m_pInput_pmem[i].buffer = (unsigned char *)buffer;
+ DEBUG_PRINT_LOW("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
+ pParam->pmem_fd, pParam->offset);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
+ return OMX_ErrorBadParameter;
+ }
+ }
+
+ DEBUG_PRINT_LOW("\nuse_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p",
+ (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer);
+ if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for "
+ "index = %u", i);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+
+ return eRet;
+}
+
+
+
+/* ======================================================================
+FUNCTION
+ omx_video::UseOutputBuffer
+
+DESCRIPTION
+ Helper function for Use buffer in the input pin
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::use_output_buffer(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes,
+ OMX_IN OMX_U8* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
+ unsigned i= 0; // Temporary counter
+ unsigned char *buf_addr = NULL;
+
+ DEBUG_PRINT_HIGH("\n Inside use_output_buffer()");
+ if(bytes != m_sOutPortDef.nBufferSize)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! "
+ "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sOutPortDef.nBufferSize);
+ return OMX_ErrorBadParameter;
+ }
+
+ if(!m_out_mem_ptr)
+ {
+ output_use_buffer = true;
+ int nBufHdrSize = 0;
+
+ DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual);
+ nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
+ /*
+ * Memory for output side involves the following:
+ * 1. Array of Buffer Headers
+ * 2. Bitmask array to hold the buffer allocation details
+ * In order to minimize the memory management entire allocation
+ * is done in one step.
+ */
+ //OMX Buffer header
+ m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
+ if(m_out_mem_ptr == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr");
+ return OMX_ErrorInsufficientResources;
+ }
+
+ m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual);
+ if(m_pOutput_pmem == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem");
+ return OMX_ErrorInsufficientResources;
+ }
+#ifdef USE_ION
+ m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
+ if(m_pOutput_ion == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ if(m_out_mem_ptr)
+ {
+ bufHdr = m_out_mem_ptr;
+ DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
+ // Settting the entire storage nicely
+ for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++)
+ {
+ bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
+ bufHdr->nAllocLen = bytes;
+ bufHdr->nFilledLen = 0;
+ bufHdr->pAppPrivate = appData;
+ bufHdr->nOutputPortIndex = PORT_INDEX_OUT;
+ bufHdr->pBuffer = NULL;
+ bufHdr++;
+ m_pOutput_pmem[i].fd = -1;
+#ifdef USE_ION
+ m_pOutput_ion[i].ion_device_fd =-1;
+ m_pOutput_ion[i].fd_ion_data.fd=-1;
+ m_pOutput_ion[i].ion_alloc_data.handle =NULL;
+#endif
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%x]\n",m_out_mem_ptr);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+
+ for(i=0; i< m_sOutPortDef.nBufferCountActual; i++)
+ {
+ if(BITMASK_ABSENT(&m_out_bm_count,i))
+ {
+ break;
+ }
+ }
+
+ if(eRet == OMX_ErrorNone)
+ {
+ if(i < m_sOutPortDef.nBufferCountActual)
+ {
+ *bufferHdr = (m_out_mem_ptr + i );
+ (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
+ (*bufferHdr)->pAppPrivate = appData;
+ BITMASK_SET(&m_out_bm_count,i);
+
+ if(!m_use_output_pmem)
+ {
+#ifdef USE_ION
+ m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(
+ m_sOutPortDef.nBufferSize,
+ &m_pOutput_ion[i].ion_alloc_data,
+ &m_pOutput_ion[i].fd_ion_data,CACHED);
+ if(m_pOutput_ion[i].ion_device_fd < 0) {
+ DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
+ return OMX_ErrorInsufficientResources;
+ }
+ m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
+#else
+ m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
+
+ if(m_pOutput_pmem[i].fd == 0)
+ {
+ m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
+ }
+
+ if(m_pOutput_pmem[i].fd < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
+ m_pOutput_pmem[i].offset = 0;
+ m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
+ MAP_SHARED,m_pOutput_pmem[i].fd,0);
+ if(m_pOutput_pmem[i].buffer == MAP_FAILED)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: mmap() Failed");
+ close(m_pOutput_pmem[i].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pOutput_ion[i]);
+#endif
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else
+ {
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate);
+ DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam);
+
+ if(pParam)
+ {
+ DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset);
+ m_pOutput_pmem[i].fd = pParam->pmem_fd;
+ m_pOutput_pmem[i].offset = pParam->offset;
+ m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
+ m_pOutput_pmem[i].buffer = (unsigned char *)buffer;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case");
+ return OMX_ErrorBadParameter;
+ }
+ buf_addr = (unsigned char *)buffer;
+ }
+
+ DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p",
+ (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer);
+ if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true)
+ {
+ DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
+ "index = %u", i);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ return eRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_video::UseBuffer
+
+DESCRIPTION
+ OMX Use Buffer method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None , if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::use_buffer(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes,
+ OMX_IN OMX_U8* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ if(port == PORT_INDEX_IN)
+ {
+ eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
+ }
+ else if(port == PORT_INDEX_OUT)
+ {
+ eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ if(eRet == OMX_ErrorNone)
+ {
+ if(allocate_done())
+ {
+ if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ {
+ // Send the callback now
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
+ post_event(OMX_CommandStateSet,OMX_StateIdle,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ }
+ if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated)
+ {
+ if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
+ {
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
+ post_event(OMX_CommandPortEnable,
+ PORT_INDEX_IN,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+
+ }
+ else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated)
+ {
+ if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
+ {
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
+ post_event(OMX_CommandPortEnable,
+ PORT_INDEX_OUT,
+ OMX_COMPONENT_GENERATE_EVENT);
+ m_event_port_settings_sent = false;
+ }
+ }
+ }
+ return eRet;
+}
+
+OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
+{
+ unsigned int index = 0;
+ OMX_U8 *temp_buff ;
+
+ if(bufferHdr == NULL || m_inp_mem_ptr == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]",
+ bufferHdr, m_inp_mem_ptr);
+ return OMX_ErrorBadParameter;
+ }
+
+ index = bufferHdr - m_inp_mem_ptr;
+#ifdef _ANDROID_ICS_
+ if(meta_mode_enable)
+ {
+ if(index < m_sInPortDef.nBufferCountActual)
+ {
+ memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
+ memset(&meta_buffers[index], 0, sizeof(meta_buffers[index]));
+ }
+ return OMX_ErrorNone;
+ }
+#endif
+ if(index < m_sInPortDef.nBufferCountActual &&
+ dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf");
+ }
+
+ if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem)
+ {
+ if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false)
+ {
+ DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case");
+ munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
+ close (m_pInput_pmem[index].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pInput_ion[index]);
+#endif
+ m_pInput_pmem[index].fd = -1;
+ }
+ else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true &&
+ m_use_input_pmem == OMX_FALSE))
+ {
+ DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case");
+ if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf");
+ }
+ munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
+ close (m_pInput_pmem[index].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pInput_ion[index]);
+#endif
+ m_pInput_pmem[index].fd = -1;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case");
+ }
+ }
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
+{
+ unsigned int index = 0;
+ OMX_U8 *temp_buff ;
+
+ if(bufferHdr == NULL || m_out_mem_ptr == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]",
+ bufferHdr, m_out_mem_ptr);
+ return OMX_ErrorBadParameter;
+ }
+ index = bufferHdr - m_out_mem_ptr;
+
+ if(index < m_sOutPortDef.nBufferCountActual &&
+ dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true)
+ {
+ DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
+ }
+
+ if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem)
+ {
+ if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false )
+ {
+ DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case");
+ munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size);
+ close (m_pOutput_pmem[index].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pOutput_ion[index]);
+#endif
+ m_pOutput_pmem[index].fd = -1;
+ }
+ else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true
+ && m_use_output_pmem == OMX_FALSE))
+ {
+ DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case");
+ if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true)
+ {
+ DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
+ }
+ munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size);
+ close (m_pOutput_pmem[index].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pOutput_ion[index]);
+#endif
+ m_pOutput_pmem[index].fd = -1;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case");
+ }
+ }
+ return OMX_ErrorNone;
+}
+#ifdef _ANDROID_ICS_
+OMX_ERRORTYPE omx_video::allocate_input_meta_buffer(
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_PTR appData,
+ OMX_U32 bytes)
+{
+ unsigned index = 0;
+ if(!bufferHdr || bytes != sizeof(encoder_media_buffer_type))
+ {
+ DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %d",
+ bufferHdr,bytes);
+ return OMX_ErrorBadParameter;
+ }
+ if(!m_inp_mem_ptr)
+ m_inp_mem_ptr = meta_buffer_hdr;
+ for(index = 0;((index < m_sInPortDef.nBufferCountActual) &&
+ meta_buffer_hdr[index].pBuffer); index++);
+ if(index == m_sInPortDef.nBufferCountActual)
+ {
+ DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer");
+ return OMX_ErrorBadParameter;
+ }
+ BITMASK_SET(&m_inp_bm_count,index);
+ *bufferHdr = &meta_buffer_hdr[index];
+ memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
+ meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]);
+ meta_buffer_hdr[index].nAllocLen = bytes;
+ meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION;
+ meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN;
+ meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index];
+ meta_buffer_hdr[index].pAppPrivate = appData;
+ return OMX_ErrorNone;
+}
+#endif
+/* ======================================================================
+FUNCTION
+ omx_venc::AllocateInputBuffer
+
+DESCRIPTION
+ Helper function for allocate buffer in the input pin
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::allocate_input_buffer(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes)
+{
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned i = 0;
+
+ DEBUG_PRINT_HIGH("\n allocate_input_buffer()::");
+ if(bytes != m_sInPortDef.nBufferSize)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]\n",
+ bytes, m_sInPortDef.nBufferSize);
+ return OMX_ErrorBadParameter;
+ }
+
+ if(!m_inp_mem_ptr)
+ {
+ DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__,
+ m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountActual);
+ m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
+ calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
+ if(m_inp_mem_ptr == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr");
+ return OMX_ErrorInsufficientResources;
+ }
+
+ m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
+
+ if(m_pInput_pmem == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem");
+ return OMX_ErrorInsufficientResources;
+ }
+#ifdef USE_ION
+ m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
+ if(m_pInput_ion == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
+ {
+ m_pInput_pmem[i].fd = -1;
+#ifdef USE_ION
+ m_pInput_ion[i].ion_device_fd =-1;
+ m_pInput_ion[i].fd_ion_data.fd =-1;
+ m_pInput_ion[i].ion_alloc_data.handle=NULL;
+#endif
+ }
+ }
+
+ for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
+ {
+ if(BITMASK_ABSENT(&m_inp_bm_count,i))
+ {
+ break;
+ }
+ }
+ if(i < m_sInPortDef.nBufferCountActual)
+ {
+
+ *bufferHdr = (m_inp_mem_ptr + i);
+ (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
+ (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize;
+ (*bufferHdr)->pAppPrivate = appData;
+ (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN;
+
+#ifdef USE_ION
+ m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
+ &m_pInput_ion[i].ion_alloc_data,
+ &m_pInput_ion[i].fd_ion_data,CACHED);
+ if(m_pInput_ion[i].ion_device_fd < 0) {
+ DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
+ return OMX_ErrorInsufficientResources;
+ }
+
+ m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
+#else
+ m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
+
+ if(m_pInput_pmem[i].fd == 0)
+ {
+ m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
+ }
+
+ if(m_pInput_pmem[i].fd < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed\n");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
+ m_pInput_pmem[i].offset = 0;
+
+ m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
+ MAP_SHARED,m_pInput_pmem[i].fd,0);
+ if(m_pInput_pmem[i].buffer == MAP_FAILED)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: mmap FAILED= %d\n", errno);
+ close(m_pInput_pmem[i].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pInput_ion[i]);
+#endif
+ return OMX_ErrorInsufficientResources;
+ }
+
+ (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer;
+
+ BITMASK_SET(&m_inp_bm_count,i);
+ //here change the I/P param here from buf_adr to pmem
+ if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call"
+ "for index [%d]\n", i);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+
+ return eRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_venc::AllocateOutputBuffer
+
+DESCRIPTION
+ Helper fn for AllocateBuffer in the output pin
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything went well.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::allocate_output_buffer(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
+ unsigned i= 0; // Temporary counter
+
+ DEBUG_PRINT_HIGH("\n allocate_output_buffer()::");
+ if(!m_out_mem_ptr)
+ {
+ int nBufHdrSize = 0;
+ DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__,
+ m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountActual);
+ nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
+
+ /*
+ * Memory for output side involves the following:
+ * 1. Array of Buffer Headers
+ * 2. Bitmask array to hold the buffer allocation details
+ * In order to minimize the memory management entire allocation
+ * is done in one step.
+ */
+ m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
+
+#ifdef USE_ION
+ m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
+ if(m_pOutput_ion == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual);
+ if(m_pOutput_pmem == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem");
+ return OMX_ErrorInsufficientResources;
+ }
+ if(m_out_mem_ptr && m_pOutput_pmem)
+ {
+ bufHdr = m_out_mem_ptr;
+
+ for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++)
+ {
+ bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
+ // Set the values when we determine the right HxW param
+ bufHdr->nAllocLen = bytes;
+ bufHdr->nFilledLen = 0;
+ bufHdr->pAppPrivate = appData;
+ bufHdr->nOutputPortIndex = PORT_INDEX_OUT;
+ bufHdr->pBuffer = NULL;
+ bufHdr++;
+ m_pOutput_pmem[i].fd = -1;
+#ifdef USE_ION
+ m_pOutput_ion[i].ion_device_fd =-1;
+ m_pOutput_ion[i].fd_ion_data.fd=-1;
+ m_pOutput_ion[i].ion_alloc_data.handle =NULL;
+#endif
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+
+ DEBUG_PRINT_HIGH("\n actual cnt = %u", m_sOutPortDef.nBufferCountActual);
+ for(i=0; i< m_sOutPortDef.nBufferCountActual; i++)
+ {
+ if(BITMASK_ABSENT(&m_out_bm_count,i))
+ {
+ DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
+ break;
+ }
+ }
+ if(eRet == OMX_ErrorNone)
+ {
+ if(i < m_sOutPortDef.nBufferCountActual)
+ {
+#ifdef USE_ION
+ m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize,
+ &m_pOutput_ion[i].ion_alloc_data,
+ &m_pOutput_ion[i].fd_ion_data,CACHED);
+ if(m_pOutput_ion[i].ion_device_fd < 0) {
+ DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
+ return OMX_ErrorInsufficientResources;
+ }
+ m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
+#else
+ m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
+ if(m_pOutput_pmem[i].fd == 0)
+ {
+ m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
+ }
+
+ if(m_pOutput_pmem[i].fd < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
+ m_pOutput_pmem[i].offset = 0;
+ m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
+ MAP_SHARED,m_pOutput_pmem[i].fd,0);
+ if(m_pOutput_pmem[i].buffer == MAP_FAILED)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer");
+ close (m_pOutput_pmem[i].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pOutput_ion[i]);
+#endif
+ return OMX_ErrorInsufficientResources;
+ }
+
+ *bufferHdr = (m_out_mem_ptr + i );
+ (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
+ (*bufferHdr)->pAppPrivate = appData;
+
+ BITMASK_SET(&m_out_bm_count,i);
+
+ if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call"
+ "for index [%d]\n", i);
+ }
+ }
+
+ return eRet;
+}
+
+
+// AllocateBuffer -- API Call
+/* ======================================================================
+FUNCTION
+ omx_video::AllocateBuffer
+
+DESCRIPTION
+ Returns zero if all the buffers released..
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes)
+{
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
+
+ DEBUG_PRINT_LOW("\n Allocate buffer of size = %d on port %d \n", bytes, (int)port);
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+
+ // What if the client calls again.
+ if(port == PORT_INDEX_IN)
+ {
+#ifdef _ANDROID_ICS_
+ if(meta_mode_enable)
+ eRet = allocate_input_meta_buffer(bufferHdr,appData,bytes);
+ else
+#endif
+ eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
+ }
+ else if(port == PORT_INDEX_OUT)
+ {
+ eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
+ if(eRet == OMX_ErrorNone)
+ {
+ if(allocate_done())
+ {
+ if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ {
+ // Send the callback now
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
+ post_event(OMX_CommandStateSet,OMX_StateIdle,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ }
+ if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated)
+ {
+ if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
+ {
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
+ post_event(OMX_CommandPortEnable,
+ PORT_INDEX_IN,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ }
+ if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated)
+ {
+ if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
+ {
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
+ post_event(OMX_CommandPortEnable,
+ PORT_INDEX_OUT,
+ OMX_COMPONENT_GENERATE_EVENT);
+ m_event_port_settings_sent = false;
+ }
+ }
+ }
+ DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
+ return eRet;
+}
+
+
+// Free Buffer - API call
+/* ======================================================================
+FUNCTION
+ omx_video::FreeBuffer
+
+DESCRIPTION
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned int nPortIndex;
+
+ DEBUG_PRINT_LOW("In for decoder free_buffer \n");
+
+ if(m_state == OMX_StateIdle &&
+ (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
+ {
+ DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
+ }
+ else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
+ (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT))
+ {
+ DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
+ }
+ else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n");
+ post_event(OMX_EventError,
+ OMX_ErrorPortUnpopulated,
+ OMX_COMPONENT_GENERATE_EVENT);
+
+ return eRet;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n");
+ post_event(OMX_EventError,
+ OMX_ErrorPortUnpopulated,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+
+ if(port == PORT_INDEX_IN)
+ {
+ // check if the buffer is valid
+ nPortIndex = buffer - m_inp_mem_ptr;
+
+ DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n",
+ nPortIndex, m_sInPortDef.nBufferCountActual);
+ if(nPortIndex < m_sInPortDef.nBufferCountActual)
+ {
+ // Clear the bit associated with it.
+ BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
+ free_input_buffer (buffer);
+ m_sInPortDef.bPopulated = OMX_FALSE;
+
+ /*Free the Buffer Header*/
+ if(release_input_done()
+#ifdef _ANDROID_ICS_
+ && !meta_mode_enable
+#endif
+ )
+ {
+ input_use_buffer = false;
+ if(m_inp_mem_ptr)
+ {
+ DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n");
+ free (m_inp_mem_ptr);
+ m_inp_mem_ptr = NULL;
+ }
+ if(m_pInput_pmem)
+ {
+ DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n");
+ free(m_pInput_pmem);
+ m_pInput_pmem = NULL;
+ }
+#ifdef USE_ION
+ if(m_pInput_ion)
+ {
+ DEBUG_PRINT_LOW("Freeing m_pInput_ion\n");
+ free(m_pInput_ion);
+ m_pInput_ion = NULL;
+ }
+#endif
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
+ && release_input_done())
+ {
+ DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
+ post_event(OMX_CommandPortDisable,
+ PORT_INDEX_IN,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ }
+ else if(port == PORT_INDEX_OUT)
+ {
+ // check if the buffer is valid
+ nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
+
+ DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n",
+ nPortIndex, m_sOutPortDef.nBufferCountActual);
+ if(nPortIndex < m_sOutPortDef.nBufferCountActual)
+ {
+ // Clear the bit associated with it.
+ BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
+ m_sOutPortDef.bPopulated = OMX_FALSE;
+ free_output_buffer (buffer);
+
+ if(release_output_done())
+ {
+ output_use_buffer = false;
+ if(m_out_mem_ptr)
+ {
+ DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n");
+ free (m_out_mem_ptr);
+ m_out_mem_ptr = NULL;
+ }
+ if(m_pOutput_pmem)
+ {
+ DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n");
+ free(m_pOutput_pmem);
+ m_pOutput_pmem = NULL;
+ }
+#ifdef USE_ION
+ if(m_pOutput_ion)
+ {
+ DEBUG_PRINT_LOW("Freeing m_pOutput_ion\n");
+ free(m_pOutput_ion);
+ m_pOutput_ion = NULL;
+ }
+#endif
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
+ && release_output_done() )
+ {
+ DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
+
+ DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
+ post_event(OMX_CommandPortDisable,
+ PORT_INDEX_OUT,
+ OMX_COMPONENT_GENERATE_EVENT);
+
+ }
+ }
+ else
+ {
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ if((eRet == OMX_ErrorNone) &&
+ (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
+ {
+ if(release_done())
+ {
+ if(dev_stop() != 0)
+ {
+ DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n");
+ eRet = OMX_ErrorHardware;
+ }
+ // Send the callback now
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
+ post_event(OMX_CommandStateSet, OMX_StateLoaded,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ }
+
+ return eRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_video::EmptyThisBuffer
+
+DESCRIPTION
+ This routine is used to push the encoded video frames to
+ the video decoder.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything went successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_ERRORTYPE ret1 = OMX_ErrorNone;
+ unsigned int nBufferIndex ;
+
+ DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer);
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid");
+ return OMX_ErrorBadParameter;
+ }
+
+ if(buffer->nVersion.nVersion != OMX_SPEC_VERSION)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid");
+ return OMX_ErrorVersionMismatch;
+ }
+
+ if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer");
+ return OMX_ErrorBadPortIndex;
+ }
+ if(!m_sInPortDef.bEnabled)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ nBufferIndex = buffer - m_inp_mem_ptr;
+
+ if(nBufferIndex > m_sInPortDef.nBufferCountActual )
+ {
+ DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex);
+ return OMX_ErrorBadParameter;
+ }
+
+ m_etb_count++;
+ DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
+ post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
+ return OMX_ErrorNone;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_video::empty_this_buffer_proxy
+
+DESCRIPTION
+ This routine is used to push the encoded video frames to
+ the video decoder.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything went successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_U8 *pmem_data_buf = NULL;
+ int push_cnt = 0;
+ unsigned nBufIndex = 0;
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ DEBUG_PRINT_LOW("\n ETBProxy: buffer->pBuffer[%p]\n", buffer->pBuffer);
+
+ if(buffer == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer);
+ return OMX_ErrorBadParameter;
+ }
+
+ nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
+
+ if(nBufIndex >= m_sInPortDef.nBufferCountActual)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex);
+ return OMX_ErrorBadParameter;
+ }
+
+ pending_input_buffers++;
+ if(input_flush_progress == true)
+ {
+ post_event ((unsigned int)buffer,0,
+ OMX_COMPONENT_GENERATE_EBD);
+ DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress");
+ return OMX_ErrorNone;
+ }
+#ifdef _ANDROID_ICS_
+ if(meta_mode_enable)
+ {
+ encoder_media_buffer_type *media_buffer;
+ bool met_error = false;
+ media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer;
+ if(media_buffer)
+ {
+ if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource &&
+ media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
+ met_error = true;
+ } else {
+ if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource)
+ {
+ if(media_buffer->meta_handle == NULL) {
+ met_error = true;
+ }
+ else if((media_buffer->meta_handle->numFds != 1 &&
+ media_buffer->meta_handle->numInts != 2))
+ {
+ met_error = true;
+ }
+ }
+ }
+ } else {
+ met_error = true;
+ }
+ if(met_error)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unkown source/metahandle in ETB call");
+ post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorBadParameter;
+ }
+
+ struct pmem Input_pmem_info;
+ if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource)
+ {
+ Input_pmem_info.buffer = media_buffer;
+ Input_pmem_info.fd = media_buffer->meta_handle->data[0];
+ Input_pmem_info.offset = media_buffer->meta_handle->data[1];
+ Input_pmem_info.size = media_buffer->meta_handle->data[2];
+ DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
+ Input_pmem_info.offset,
+ Input_pmem_info.size);
+
+ } else {
+ private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
+ Input_pmem_info.buffer = media_buffer;
+ Input_pmem_info.fd = handle->fd;
+ Input_pmem_info.offset = 0;
+ Input_pmem_info.size = handle->size;
+ }
+ if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
+ DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
+ post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorBadParameter;
+ }
+ }
+ else if(input_use_buffer && !m_use_input_pmem)
+#else
+ if(input_use_buffer && !m_use_input_pmem)
+#endif
+ {
+ DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data");
+ pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
+
+ memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
+ buffer->nFilledLen);
+ DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
+ }
+#ifdef _COPPER_
+ if(dev_empty_buf(buffer, pmem_data_buf,nBufIndex,m_pInput_pmem[nBufIndex].fd) != true)
+#else
+ if(dev_empty_buf(buffer, pmem_data_buf,0,0) != true)
+#endif
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed");
+#ifdef _ANDROID_ICS_
+ omx_release_meta_buffer(buffer);
+#endif
+ post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
+ /*Generate an async error and move to invalid state*/
+ pending_input_buffers--;
+ return OMX_ErrorBadParameter;
+ }
+
+ return ret;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_video::FillThisBuffer
+
+DESCRIPTION
+ IL client uses this method to release the frame buffer
+ after displaying them.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer);
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)))
+ {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n");
+ return OMX_ErrorBadParameter;
+ }
+
+ if(buffer->nVersion.nVersion != OMX_SPEC_VERSION)
+ {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n");
+ return OMX_ErrorVersionMismatch;
+ }
+
+ if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT)
+ {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n");
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if(!m_sOutPortDef.bEnabled)
+ {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB);
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_video::fill_this_buffer_proxy
+
+DESCRIPTION
+ IL client uses this method to release the frame buffer
+ after displaying them.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::fill_this_buffer_proxy(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
+{
+ OMX_U8 *pmem_data_buf = NULL;
+ OMX_ERRORTYPE nRet = OMX_ErrorNone;
+
+ DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer);
+
+ if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) )
+ {
+ DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n");
+ return OMX_ErrorBadParameter;
+ }
+
+ pending_output_buffers++;
+ /*Return back the output buffer to client*/
+ if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true)
+ {
+ DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress");
+ post_event ((unsigned int)bufferAdd,0,
+ OMX_COMPONENT_GENERATE_FBD);
+ return OMX_ErrorNone;
+ }
+
+ if(output_use_buffer && !m_use_output_pmem)
+ {
+ DEBUG_PRINT_LOW("\n Heap UseBuffer case");
+ pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
+ }
+
+ if(dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed");
+ post_event ((unsigned int)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD);
+ pending_output_buffers--;
+ return OMX_ErrorBadParameter;
+ }
+
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_video::SetCallbacks
+
+DESCRIPTION
+ Set the callbacks.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_CALLBACKTYPE* callbacks,
+ OMX_IN OMX_PTR appData)
+{
+
+ m_pCallbacks = *callbacks;
+ DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
+ m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
+ m_app_data = appData;
+ return OMX_ErrorNotImplemented;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_venc::UseEGLImage
+
+DESCRIPTION
+ OMX Use EGL Image method implementation <TBD>.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ Not Implemented error.
+
+========================================================================== */
+OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN void* eglImage)
+{
+ DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented \n");
+ return OMX_ErrorNotImplemented;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_venc::ComponentRoleEnum
+
+DESCRIPTION
+ OMX Component Role Enum method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything is successful.
+========================================================================== */
+OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_U8* role,
+ OMX_IN OMX_U32 index)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if((0 == index) && role)
+ {
+ strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
+ DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
+ }
+ else
+ {
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if((0 == index) && role)
+ {
+ strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
+ DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if((0 == index) && role)
+ {
+ strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
+ DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if((0 == index) && role)
+ {
+ strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
+ DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if((0 == index) && role)
+ {
+ strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
+ DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
+ }
+ else
+ {
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if((0 == index) && role)
+ {
+ strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
+ DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if((0 == index) && role)
+ {
+ strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
+ DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n");
+ eRet = OMX_ErrorInvalidComponentName;
+ }
+ return eRet;
+}
+
+
+
+
+/* ======================================================================
+FUNCTION
+ omx_venc::AllocateDone
+
+DESCRIPTION
+ Checks if entire buffer pool is allocated by IL Client or not.
+ Need this to move to IDLE state.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false.
+
+========================================================================== */
+bool omx_video::allocate_done(void)
+{
+ bool bRet = false;
+ bool bRet_In = false;
+ bool bRet_Out = false;
+
+ bRet_In = allocate_input_done();
+ bRet_Out = allocate_output_done();
+
+ if(bRet_In && bRet_Out)
+ {
+ bRet = true;
+ }
+
+ return bRet;
+}
+/* ======================================================================
+FUNCTION
+ omx_venc::AllocateInputDone
+
+DESCRIPTION
+ Checks if I/P buffer pool is allocated by IL Client or not.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false.
+
+========================================================================== */
+bool omx_video::allocate_input_done(void)
+{
+ bool bRet = false;
+ unsigned i=0;
+
+ if(m_inp_mem_ptr == NULL)
+ {
+ return bRet;
+ }
+ if(m_inp_mem_ptr )
+ {
+ for(;i<m_sInPortDef.nBufferCountActual;i++)
+ {
+ if(BITMASK_ABSENT(&m_inp_bm_count,i))
+ {
+ break;
+ }
+ }
+ }
+ if(i==m_sInPortDef.nBufferCountActual)
+ {
+ bRet = true;
+ }
+ if(i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled)
+ {
+ m_sInPortDef.bPopulated = OMX_TRUE;
+ }
+ return bRet;
+}
+/* ======================================================================
+FUNCTION
+ omx_venc::AllocateOutputDone
+
+DESCRIPTION
+ Checks if entire O/P buffer pool is allocated by IL Client or not.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false.
+
+========================================================================== */
+bool omx_video::allocate_output_done(void)
+{
+ bool bRet = false;
+ unsigned j=0;
+
+ if(m_out_mem_ptr == NULL)
+ {
+ return bRet;
+ }
+
+ if(m_out_mem_ptr )
+ {
+ for(;j<m_sOutPortDef.nBufferCountActual;j++)
+ {
+ if(BITMASK_ABSENT(&m_out_bm_count,j))
+ {
+ break;
+ }
+ }
+ }
+
+ if(j==m_sOutPortDef.nBufferCountActual)
+ {
+ bRet = true;
+ }
+
+ if(j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled)
+ {
+ m_sOutPortDef.bPopulated = OMX_TRUE;
+ }
+ return bRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_venc::ReleaseDone
+
+DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_video::release_done(void)
+{
+ bool bRet = false;
+ DEBUG_PRINT_LOW("Inside release_done()\n");
+ if(release_input_done())
+ {
+ if(release_output_done())
+ {
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_venc::ReleaseOutputDone
+
+DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_video::release_output_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Inside release_output_done()\n");
+ if(m_out_mem_ptr)
+ {
+ for(;j<m_sOutPortDef.nBufferCountActual;j++)
+ {
+ if(BITMASK_PRESENT(&m_out_bm_count,j))
+ {
+ break;
+ }
+ }
+ if(j==m_sOutPortDef.nBufferCountActual)
+ {
+ bRet = true;
+ }
+ }
+ else
+ {
+ bRet = true;
+ }
+ return bRet;
+}
+/* ======================================================================
+FUNCTION
+ omx_venc::ReleaseInputDone
+
+DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_video::release_input_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Inside release_input_done()\n");
+ if(m_inp_mem_ptr)
+ {
+ for(;j<m_sInPortDef.nBufferCountActual;j++)
+ {
+ if( BITMASK_PRESENT(&m_inp_bm_count,j))
+ {
+ break;
+ }
+ }
+ if(j==m_sInPortDef.nBufferCountActual)
+ {
+ bRet = true;
+ }
+ }
+ else
+ {
+ bRet = true;
+ }
+ return bRet;
+}
+
+OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer)
+{
+ DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x",
+ buffer->pBuffer, buffer->nFlags);
+ if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual))
+ {
+ return OMX_ErrorBadParameter;
+ }
+
+ pending_output_buffers--;
+
+ extra_data_handle.create_extra_data(buffer);
+
+ if (m_sDebugSliceinfo) {
+ if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
+ DEBUG_PRINT_HIGH("parsing extradata");
+ extra_data_handle.parse_extra_data(buffer);
+ }
+ }
+ /* For use buffer we need to copy the data */
+ if(m_pCallbacks.FillBufferDone)
+ {
+ if(buffer->nFilledLen > 0)
+ {
+ m_fbd_count++;
+
+#ifdef OUTPUT_BUFFER_LOG
+ if(outputBufferFile1)
+ {
+ fwrite((const char *)buffer->pBuffer, buffer->nFilledLen, 1, outputBufferFile1);
+ }
+#endif
+ }
+ m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
+ }
+ else
+ {
+ return OMX_ErrorBadParameter;
+ }
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE* buffer)
+{
+ DEBUG_PRINT_LOW("empty_buffer_done: buffer->pBuffer[%p]", buffer->pBuffer);
+ if(buffer == NULL || ((buffer - m_inp_mem_ptr) > m_sInPortDef.nBufferCountActual))
+ {
+ return OMX_ErrorBadParameter;
+ }
+
+ pending_input_buffers--;
+
+ if(m_pCallbacks.EmptyBufferDone)
+ {
+ m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
+ }
+ return OMX_ErrorNone;
+}
+
+void omx_video::complete_pending_buffer_done_cbs()
+{
+ unsigned p1;
+ unsigned p2;
+ unsigned ident;
+ omx_cmd_queue tmp_q, pending_bd_q;
+ pthread_mutex_lock(&m_lock);
+ // pop all pending GENERATE FDB from ftb queue
+ while (m_ftb_q.m_size)
+ {
+ m_ftb_q.pop_entry(&p1,&p2,&ident);
+ if(ident == OMX_COMPONENT_GENERATE_FBD)
+ {
+ pending_bd_q.insert_entry(p1,p2,ident);
+ }
+ else
+ {
+ tmp_q.insert_entry(p1,p2,ident);
+ }
+ }
+ //return all non GENERATE FDB to ftb queue
+ while(tmp_q.m_size)
+ {
+ tmp_q.pop_entry(&p1,&p2,&ident);
+ m_ftb_q.insert_entry(p1,p2,ident);
+ }
+ // pop all pending GENERATE EDB from etb queue
+ while (m_etb_q.m_size)
+ {
+ m_etb_q.pop_entry(&p1,&p2,&ident);
+ if(ident == OMX_COMPONENT_GENERATE_EBD)
+ {
+ pending_bd_q.insert_entry(p1,p2,ident);
+ }
+ else
+ {
+ tmp_q.insert_entry(p1,p2,ident);
+ }
+ }
+ //return all non GENERATE FDB to etb queue
+ while(tmp_q.m_size)
+ {
+ tmp_q.pop_entry(&p1,&p2,&ident);
+ m_etb_q.insert_entry(p1,p2,ident);
+ }
+ pthread_mutex_unlock(&m_lock);
+ // process all pending buffer dones
+ while(pending_bd_q.m_size)
+ {
+ pending_bd_q.pop_entry(&p1,&p2,&ident);
+ switch(ident)
+ {
+ case OMX_COMPONENT_GENERATE_EBD:
+ if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
+ omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FBD:
+ if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
+ {
+ DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
+ omx_report_error ();
+ }
+ break;
+ }
+ }
+}
+
+#ifdef MAX_RES_720P
+OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ if(!profileLevelType)
+ return OMX_ErrorBadParameter;
+
+ if(profileLevelType->nPortIndex == 1) {
+ if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
+ {
+ if (profileLevelType->nProfileIndex == 0)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel31;
+ }
+ else if (profileLevelType->nProfileIndex == 1)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel31;
+ }
+ else if(profileLevelType->nProfileIndex == 2)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel31;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
+ profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
+ {
+ if (profileLevelType->nProfileIndex == 0)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
+ profileLevelType->eLevel = OMX_VIDEO_H263Level70;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
+ {
+ if (profileLevelType->nProfileIndex == 0)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
+ }
+ else if(profileLevelType->nProfileIndex == 1)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
+ profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
+ profileLevelType->eProfile,profileLevelType->eLevel);
+ return eRet;
+}
+#endif
+
+#ifdef MAX_RES_1080P
+OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ if(!profileLevelType)
+ return OMX_ErrorBadParameter;
+
+ if(profileLevelType->nPortIndex == 1) {
+ if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
+ {
+ if (profileLevelType->nProfileIndex == 0)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
+
+ }
+ else if (profileLevelType->nProfileIndex == 1)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
+ }
+ else if(profileLevelType->nProfileIndex == 2)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
+ profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
+ {
+ if (profileLevelType->nProfileIndex == 0)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
+ profileLevelType->eLevel = OMX_VIDEO_H263Level70;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
+ {
+ if (profileLevelType->nProfileIndex == 0)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
+ }
+ else if(profileLevelType->nProfileIndex == 1)
+ {
+ profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
+ profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
+ profileLevelType->eProfile,profileLevelType->eLevel);
+ return eRet;
+}
+
+#ifdef USE_ION
+int omx_video::alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data,
+ struct ion_fd_data *fd_data,int flag)
+{
+ struct venc_ion buf_ion_info;
+ int ion_device_fd =-1,rc=0,ion_dev_flags = 0;
+ if (size <=0 || !alloc_data || !fd_data) {
+ DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory");
+ return -EINVAL;
+ }
+ if(flag == CACHED) {
+ ion_dev_flags = O_RDONLY;
+ } else if(flag == UNCACHED) {
+ ion_dev_flags = O_RDONLY ;//| O_DSYNC;
+ }
+ ion_device_fd = open (MEM_DEVICE,ion_dev_flags);
+ if(ion_device_fd < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
+ return ion_device_fd;
+ }
+ alloc_data->len = size;
+ alloc_data->align = 4096;
+ alloc_data->flags = (ION_HEAP(MEM_HEAP_ID) |
+ ION_HEAP(ION_IOMMU_HEAP_ID));
+ rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
+ if(rc || !alloc_data->handle) {
+ DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
+ alloc_data->handle =NULL;
+ close(ion_device_fd);
+ ion_device_fd = -1;
+ return ion_device_fd;
+ }
+ fd_data->handle = alloc_data->handle;
+ rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data);
+ if(rc) {
+ DEBUG_PRINT_ERROR("\n ION MAP failed ");
+ buf_ion_info.ion_alloc_data = *alloc_data;
+ buf_ion_info.ion_device_fd = ion_device_fd;
+ buf_ion_info.fd_ion_data = *fd_data;
+ free_ion_memory(&buf_ion_info);
+ fd_data->fd =-1;
+ ion_device_fd =-1;
+ }
+ return ion_device_fd;
+}
+
+void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
+{
+ if (!buf_ion_info) {
+ DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory");
+ return;
+ }
+ if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
+ &buf_ion_info->ion_alloc_data.handle)) {
+ DEBUG_PRINT_ERROR("\n ION free failed ");
+ return;
+ }
+ close(buf_ion_info->ion_device_fd);
+ buf_ion_info->ion_alloc_data.handle = NULL;
+ buf_ion_info->ion_device_fd = -1;
+ buf_ion_info->fd_ion_data.fd = -1;
+}
+#endif
+#endif
+#ifdef _ANDROID_ICS_
+void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
+{
+ if(buffer && meta_mode_enable)
+ {
+ encoder_media_buffer_type *media_ptr;
+ struct pmem Input_pmem;
+ bool meta_error = false;
+ media_ptr = (encoder_media_buffer_type *) buffer->pBuffer;
+ if(media_ptr && media_ptr->meta_handle)
+ {
+ if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource &&
+ media_ptr->meta_handle->numFds == 1 &&
+ media_ptr->meta_handle->numInts == 2) {
+ Input_pmem.fd = media_ptr->meta_handle->data[0];
+ Input_pmem.buffer = media_ptr;
+ Input_pmem.size = media_ptr->meta_handle->data[2];
+ Input_pmem.offset = media_ptr->meta_handle->data[1];
+ DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
+ Input_pmem.offset,
+ Input_pmem.size);
+ } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
+ private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle;
+ Input_pmem.buffer = media_ptr;
+ Input_pmem.fd = handle->fd;
+ Input_pmem.offset = 0;
+ Input_pmem.size = handle->size;
+ } else {
+ meta_error = true;
+ DEBUG_PRINT_ERROR(" Meta Error set in EBD");
+ }
+ if(!meta_error)
+ meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
+ if(meta_error)
+ {
+ DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d",
+ input_flush_progress);
+ }
+ }
+ }
+}
+#endif
diff --git a/mm-video/vidc/venc/src/omx_video_encoder.cpp b/mm-video/vidc/venc/src/omx_video_encoder.cpp
new file mode 100755
index 0000000..cbcb47c
--- /dev/null
+++ b/mm-video/vidc/venc/src/omx_video_encoder.cpp
@@ -0,0 +1,1650 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#include "omx_video_encoder.h"
+#include <string.h>
+#include "video_encoder_device.h"
+#include <stdio.h>
+#ifdef _ANDROID_ICS_
+#include <media/hardware/HardwareAPI.h>
+#endif
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#endif
+#ifndef _ANDROID_
+#include <glib.h>
+#define strlcpy g_strlcpy
+#endif
+/*----------------------------------------------------------------------------
+* Preprocessor Definitions and Constants
+* -------------------------------------------------------------------------*/
+
+#define OMX_SPEC_VERSION 0x00000101
+#define OMX_INIT_STRUCT(_s_, _name_) \
+ memset((_s_), 0x0, sizeof(_name_)); \
+ (_s_)->nSize = sizeof(_name_); \
+ (_s_)->nVersion.nVersion = OMX_SPEC_VERSION
+
+extern int m_pipe;
+
+// factory function executed by the core to create instances
+void *get_omx_component_factory_fn(void)
+{
+ return(new omx_venc);
+}
+
+//constructor
+
+omx_venc::omx_venc()
+{
+#ifdef _ANDROID_ICS_
+ meta_mode_enable = false;
+ memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr));
+ memset(meta_buffers,0,sizeof(meta_buffers));
+ mUseProxyColorFormat = false;
+#endif
+}
+
+omx_venc::~omx_venc()
+{
+ //nothing to do
+}
+
+/* ======================================================================
+FUNCTION
+ omx_venc::ComponentInit
+
+DESCRIPTION
+ Initialize the component.
+
+PARAMETERS
+ ctxt -- Context information related to the self.
+ id -- Event identifier. This could be any of the following:
+ 1. Command completion event
+ 2. Buffer done callback event
+ 3. Frame done callback event
+
+RETURN VALUE
+ None.
+
+========================================================================== */
+OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role)
+{
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ int fds[2];
+ int r;
+
+ OMX_VIDEO_CODINGTYPE codec_type;
+
+ DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_init()");
+ // Copy the role information which provides the decoder m_nkind
+ strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE);
+
+ if(!strncmp((char *)m_nkind,"OMX.qcom.video.encoder.mpeg4",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ strlcpy((char *)m_cRole, "video_encoder.mpeg4",\
+ OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingMPEG4;
+ }
+ else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ strlcpy((char *)m_cRole, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingH263;
+ }
+ else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ strlcpy((char *)m_cRole, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingAVC;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unknown Component\n");
+ eRet = OMX_ErrorInvalidComponentName;
+ }
+
+
+ if(eRet != OMX_ErrorNone)
+ {
+ return eRet;
+ }
+
+ handle = new venc_dev(this);
+
+ if(handle == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: handle is NULL");
+ return OMX_ErrorInsufficientResources;
+ }
+
+ if(handle->venc_open(codec_type) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_open failed");
+ return OMX_ErrorInsufficientResources;
+ }
+
+ //Intialise the OMX layer variables
+ memset(&m_pCallbacks,0,sizeof(OMX_CALLBACKTYPE));
+
+ OMX_INIT_STRUCT(&m_sPortParam, OMX_PORT_PARAM_TYPE);
+ m_sPortParam.nPorts = 0x2;
+ m_sPortParam.nStartPortNumber = (OMX_U32) PORT_INDEX_IN;
+
+ OMX_INIT_STRUCT(&m_sPortParam_audio, OMX_PORT_PARAM_TYPE);
+ m_sPortParam_audio.nPorts = 0;
+ m_sPortParam_audio.nStartPortNumber = 0;
+
+ OMX_INIT_STRUCT(&m_sPortParam_img, OMX_PORT_PARAM_TYPE);
+ m_sPortParam_img.nPorts = 0;
+ m_sPortParam_img.nStartPortNumber = 0;
+
+ OMX_INIT_STRUCT(&m_sParamBitrate, OMX_VIDEO_PARAM_BITRATETYPE);
+ m_sParamBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sParamBitrate.eControlRate = OMX_Video_ControlRateVariableSkipFrames;
+ m_sParamBitrate.nTargetBitrate = 64000;
+
+ OMX_INIT_STRUCT(&m_sConfigBitrate, OMX_VIDEO_CONFIG_BITRATETYPE);
+ m_sConfigBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sConfigBitrate.nEncodeBitrate = 64000;
+
+ OMX_INIT_STRUCT(&m_sConfigFramerate, OMX_CONFIG_FRAMERATETYPE);
+ m_sConfigFramerate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sConfigFramerate.xEncodeFramerate = 30 << 16;
+
+ OMX_INIT_STRUCT(&m_sConfigIntraRefreshVOP, OMX_CONFIG_INTRAREFRESHVOPTYPE);
+ m_sConfigIntraRefreshVOP.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sConfigIntraRefreshVOP.IntraRefreshVOP = OMX_FALSE;
+
+ OMX_INIT_STRUCT(&m_sConfigFrameRotation, OMX_CONFIG_ROTATIONTYPE);
+ m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_IN;
+ m_sConfigFrameRotation.nRotation = 0;
+
+ OMX_INIT_STRUCT(&m_sSessionQuantization, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
+ m_sSessionQuantization.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sSessionQuantization.nQpI = 9;
+ m_sSessionQuantization.nQpP = 6;
+ m_sSessionQuantization.nQpB = 2;
+
+ OMX_INIT_STRUCT(&m_sAVCSliceFMO, OMX_VIDEO_PARAM_AVCSLICEFMO);
+ m_sAVCSliceFMO.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sAVCSliceFMO.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
+ m_sAVCSliceFMO.nNumSliceGroups = 0;
+ m_sAVCSliceFMO.nSliceGroupMapType = 0;
+ OMX_INIT_STRUCT(&m_sParamProfileLevel, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
+ m_sParamProfileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+
+ OMX_INIT_STRUCT(&m_sIntraperiod, QOMX_VIDEO_INTRAPERIODTYPE);
+ m_sIntraperiod.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sIntraperiod.nPFrames = (m_sConfigFramerate.xEncodeFramerate * 2) - 1;
+
+ OMX_INIT_STRUCT(&m_sErrorCorrection, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE);
+ m_sErrorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sErrorCorrection.bEnableDataPartitioning = OMX_FALSE;
+ m_sErrorCorrection.bEnableHEC = OMX_FALSE;
+ m_sErrorCorrection.bEnableResync = OMX_FALSE;
+ m_sErrorCorrection.bEnableRVLC = OMX_FALSE;
+ m_sErrorCorrection.nResynchMarkerSpacing = 0;
+
+ OMX_INIT_STRUCT(&m_sIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE);
+ m_sIntraRefresh.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshMax;
+
+ if(codec_type == OMX_VIDEO_CodingMPEG4)
+ {
+ m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple;
+ m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_MPEG4Level0;
+ }
+ else if(codec_type == OMX_VIDEO_CodingH263)
+ {
+ m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_H263ProfileBaseline;
+ m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_H263Level10;
+ }
+ else if(codec_type == OMX_VIDEO_CodingAVC)
+ {
+ m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_AVCProfileBaseline;
+ m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_AVCLevel1;
+ }
+
+ // Initialize the video parameters for input port
+ OMX_INIT_STRUCT(&m_sInPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
+ m_sInPortDef.nPortIndex= (OMX_U32) PORT_INDEX_IN;
+ m_sInPortDef.bEnabled = OMX_TRUE;
+ m_sInPortDef.bPopulated = OMX_FALSE;
+ m_sInPortDef.eDomain = OMX_PortDomainVideo;
+ m_sInPortDef.eDir = OMX_DirInput;
+ m_sInPortDef.format.video.cMIMEType = "YUV420";
+ m_sInPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH;
+ m_sInPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT;
+ m_sInPortDef.format.video.nStride = OMX_CORE_QCIF_WIDTH;
+ m_sInPortDef.format.video.nSliceHeight = OMX_CORE_QCIF_HEIGHT;
+ m_sInPortDef.format.video.nBitrate = 64000;
+ m_sInPortDef.format.video.xFramerate = 15 << 16;
+ m_sInPortDef.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+ m_sInPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+ if(dev_get_buf_req(&m_sInPortDef.nBufferCountMin,
+ &m_sInPortDef.nBufferCountActual,
+ &m_sInPortDef.nBufferSize,
+ m_sInPortDef.nPortIndex) != true)
+ {
+ eRet = OMX_ErrorUndefined;
+
+ }
+
+ // Initialize the video parameters for output port
+ OMX_INIT_STRUCT(&m_sOutPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
+ m_sOutPortDef.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sOutPortDef.bEnabled = OMX_TRUE;
+ m_sOutPortDef.bPopulated = OMX_FALSE;
+ m_sOutPortDef.eDomain = OMX_PortDomainVideo;
+ m_sOutPortDef.eDir = OMX_DirOutput;
+ m_sOutPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH;
+ m_sOutPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT;
+ m_sOutPortDef.format.video.nBitrate = 64000;
+ m_sOutPortDef.format.video.xFramerate = 15 << 16;
+ m_sOutPortDef.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+ if(codec_type == OMX_VIDEO_CodingMPEG4)
+ {
+ m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
+ }
+ else if(codec_type == OMX_VIDEO_CodingH263)
+ {
+ m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
+ }
+ else
+ {
+ m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+ }
+ if(dev_get_buf_req(&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ m_sOutPortDef.nPortIndex) != true)
+ {
+ eRet = OMX_ErrorUndefined;
+ }
+
+ // Initialize the video color format for input port
+ OMX_INIT_STRUCT(&m_sInPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ m_sInPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_IN;
+ m_sInPortFormat.nIndex = 0;
+ m_sInPortFormat.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+ m_sInPortFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+
+ // Initialize the compression format for output port
+ OMX_INIT_STRUCT(&m_sOutPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ m_sOutPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sOutPortFormat.nIndex = 0;
+ m_sOutPortFormat.eColorFormat = OMX_COLOR_FormatUnused;
+ if(codec_type == OMX_VIDEO_CodingMPEG4)
+ {
+ m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
+ }
+ else if(codec_type == OMX_VIDEO_CodingH263)
+ {
+ m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingH263;
+ }
+ else
+ {
+ m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingAVC;
+ }
+
+ // mandatory Indices for kronos test suite
+ OMX_INIT_STRUCT(&m_sPriorityMgmt, OMX_PRIORITYMGMTTYPE);
+
+ OMX_INIT_STRUCT(&m_sInBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE);
+ m_sInBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_IN;
+
+ OMX_INIT_STRUCT(&m_sOutBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE);
+ m_sOutBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+
+
+ // mp4 specific init
+ OMX_INIT_STRUCT(&m_sParamMPEG4, OMX_VIDEO_PARAM_MPEG4TYPE);
+ m_sParamMPEG4.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sParamMPEG4.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ m_sParamMPEG4.eLevel = OMX_VIDEO_MPEG4Level0;
+ m_sParamMPEG4.nSliceHeaderSpacing = 0;
+ m_sParamMPEG4.bSVH = OMX_FALSE;
+ m_sParamMPEG4.bGov = OMX_FALSE;
+ m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps
+ m_sParamMPEG4.bACPred = OMX_TRUE;
+ m_sParamMPEG4.nTimeIncRes = 30; // delta = 2 @ 15 fps
+ m_sParamMPEG4.nAllowedPictureTypes = 2; // pframe and iframe
+ m_sParamMPEG4.nHeaderExtension = 1; // number of video packet headers per vop
+ m_sParamMPEG4.bReversibleVLC = OMX_FALSE;
+
+ // h263 specific init
+ OMX_INIT_STRUCT(&m_sParamH263, OMX_VIDEO_PARAM_H263TYPE);
+ m_sParamH263.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps
+ m_sParamH263.nBFrames = 0;
+ m_sParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline;
+ m_sParamH263.eLevel = OMX_VIDEO_H263Level10;
+ m_sParamH263.bPLUSPTYPEAllowed = OMX_FALSE;
+ m_sParamH263.nAllowedPictureTypes = 2;
+ m_sParamH263.bForceRoundingTypeToZero = OMX_TRUE;
+ m_sParamH263.nPictureHeaderRepetition = 0;
+ m_sParamH263.nGOBHeaderInterval = 1;
+
+ // h264 specific init
+ OMX_INIT_STRUCT(&m_sParamAVC, OMX_VIDEO_PARAM_AVCTYPE);
+ m_sParamAVC.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sParamAVC.nSliceHeaderSpacing = 0;
+ m_sParamAVC.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps
+ m_sParamAVC.nBFrames = 0;
+ m_sParamAVC.bUseHadamard = OMX_FALSE;
+ m_sParamAVC.nRefFrames = 1;
+ m_sParamAVC.nRefIdx10ActiveMinus1 = 1;
+ m_sParamAVC.nRefIdx11ActiveMinus1 = 0;
+ m_sParamAVC.bEnableUEP = OMX_FALSE;
+ m_sParamAVC.bEnableFMO = OMX_FALSE;
+ m_sParamAVC.bEnableASO = OMX_FALSE;
+ m_sParamAVC.bEnableRS = OMX_FALSE;
+ m_sParamAVC.eProfile = OMX_VIDEO_AVCProfileBaseline;
+ m_sParamAVC.eLevel = OMX_VIDEO_AVCLevel1;
+ m_sParamAVC.nAllowedPictureTypes = 2;
+ m_sParamAVC.bFrameMBsOnly = OMX_FALSE;
+ m_sParamAVC.bMBAFF = OMX_FALSE;
+ m_sParamAVC.bEntropyCodingCABAC = OMX_FALSE;
+ m_sParamAVC.bWeightedPPrediction = OMX_FALSE;
+ m_sParamAVC.nWeightedBipredicitonMode = 0;
+ m_sParamAVC.bconstIpred = OMX_FALSE;
+ m_sParamAVC.bDirect8x8Inference = OMX_FALSE;
+ m_sParamAVC.bDirectSpatialTemporal = OMX_FALSE;
+ m_sParamAVC.nCabacInitIdc = 0;
+ m_sParamAVC.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
+
+ m_state = OMX_StateLoaded;
+ m_sExtraData = 0;
+ m_sDebugSliceinfo = 0;
+#ifdef _ANDROID_
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("vidc.venc.debug.sliceinfo", value, "0");
+ m_sDebugSliceinfo = (OMX_U32)atoi(value);
+ DEBUG_PRINT_HIGH("vidc.venc.debug.sliceinfo value is %d", m_sDebugSliceinfo);
+#endif
+
+ if(eRet == OMX_ErrorNone)
+ {
+ if(pipe(fds))
+ {
+ DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ else
+ {
+ if(fds[0] == 0 || fds[1] == 0)
+ {
+ if(pipe(fds))
+ {
+ DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ if(eRet == OMX_ErrorNone)
+ {
+ m_pipe_in = fds[0];
+ m_pipe_out = fds[1];
+ }
+ }
+ r = pthread_create(&msg_thread_id,0,message_thread,this);
+
+ if(r < 0)
+ {
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ else
+ {
+ r = pthread_create(&async_thread_id,0,async_venc_message_thread,this);
+ if(r < 0)
+ {
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ }
+
+ DEBUG_PRINT_HIGH("\n Component_init return value = 0x%x", eRet);
+ return eRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_venc::Setparameter
+
+DESCRIPTION
+ OMX Set Parameter method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_IN OMX_PTR paramData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ if(paramData == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n");
+ return OMX_ErrorBadParameter;
+ }
+
+ /*set_parameter can be called in loaded state
+ or disabled port */
+ if(m_state == OMX_StateLoaded
+ || m_sInPortDef.bEnabled == OMX_FALSE
+ || m_sOutPortDef.bEnabled == OMX_FALSE)
+ {
+ DEBUG_PRINT_LOW("Set Parameter called in valid state");
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ switch(paramIndex)
+ {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
+ (int)portDefn->format.video.nFrameHeight,
+ (int)portDefn->format.video.nFrameWidth);
+
+ if(PORT_INDEX_IN == portDefn->nPortIndex)
+ {
+ DEBUG_PRINT_LOW("\n i/p actual cnt requested = %d\n", portDefn->nBufferCountActual);
+ DEBUG_PRINT_LOW("\n i/p min cnt requested = %d\n", portDefn->nBufferCountMin);
+ DEBUG_PRINT_LOW("\n i/p buffersize requested = %d\n", portDefn->nBufferSize);
+ if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ DEBUG_PRINT_LOW("\n i/p previous actual cnt = %d\n", m_sInPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("\n i/p previous min cnt = %d\n", m_sInPortDef.nBufferCountMin);
+ memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+
+#ifdef _ANDROID_ICS_
+ if (portDefn->format.video.eColorFormat == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) {
+ m_sInPortDef.format.video.eColorFormat =
+ OMX_COLOR_FormatYUV420SemiPlanar;
+ mUseProxyColorFormat = true;
+ } //else case not needed as color format is already updated in the memcpy above
+#endif
+ /*Query Input Buffer Requirements*/
+ dev_get_buf_req (&m_sInPortDef.nBufferCountMin,
+ &m_sInPortDef.nBufferCountActual,
+ &m_sInPortDef.nBufferSize,
+ m_sInPortDef.nPortIndex);
+
+ /*Query ouput Buffer Requirements*/
+ dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ m_sOutPortDef.nPortIndex);
+ m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual;
+ }
+ else if(PORT_INDEX_OUT == portDefn->nPortIndex)
+ {
+ DEBUG_PRINT_LOW("\n o/p actual cnt requested = %d\n", portDefn->nBufferCountActual);
+ DEBUG_PRINT_LOW("\n o/p min cnt requested = %d\n", portDefn->nBufferCountMin);
+ DEBUG_PRINT_LOW("\n o/p buffersize requested = %d\n", portDefn->nBufferSize);
+ if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_set_param output failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sOutPortDef,portDefn,sizeof(struct OMX_PARAM_PORTDEFINITIONTYPE));
+ update_profile_level(); //framerate , bitrate
+
+ DEBUG_PRINT_LOW("\n o/p previous actual cnt = %d\n", m_sOutPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("\n o/p previous min cnt = %d\n", m_sOutPortDef.nBufferCountMin);
+ m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Set_parameter: Bad Port idx %d",
+ (int)portDefn->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ m_sConfigFramerate.xEncodeFramerate = portDefn->format.video.xFramerate;
+ m_sConfigBitrate.nEncodeBitrate = portDefn->format.video.nBitrate;
+ m_sParamBitrate.nTargetBitrate = portDefn->format.video.nBitrate;
+ }
+ break;
+
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
+ portFmt->eColorFormat);
+ //set the driver with the corresponding values
+ if(PORT_INDEX_IN == portFmt->nPortIndex)
+ {
+ if(handle->venc_set_param(paramData,OMX_IndexParamVideoPortFormat) != true)
+ {
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
+ portFmt->eColorFormat);
+ update_profile_level(); //framerate
+
+#ifdef _ANDROID_ICS_
+ if (portFmt->eColorFormat ==
+ (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) {
+ m_sInPortFormat.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+ mUseProxyColorFormat = true;
+ }
+ else
+#endif
+ {
+ m_sInPortFormat.eColorFormat = portFmt->eColorFormat;
+ }
+ m_sInPortFormat.xFramerate = portFmt->xFramerate;
+ }
+ //TODO if no use case for O/P port,delet m_sOutPortFormat
+ }
+ break;
+ case OMX_IndexParamVideoInit:
+ { //TODO, do we need this index set param
+ OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData);
+ DEBUG_PRINT_LOW("\n Set OMX_IndexParamVideoInit called");
+ break;
+ }
+
+ case OMX_IndexParamVideoBitrate:
+ {
+ OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoBitrate");
+ if(handle->venc_set_param(paramData,OMX_IndexParamVideoBitrate) != true)
+ {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate;
+ m_sParamBitrate.eControlRate = pParam->eControlRate;
+ update_profile_level(); //bitrate
+ m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate;
+ m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate;
+ m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate;
+ DEBUG_PRINT_LOW("\nbitrate = %u", m_sOutPortDef.format.video.nBitrate);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4:
+ {
+ OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
+ OMX_VIDEO_PARAM_MPEG4TYPE mp4_param;
+ memcpy(&mp4_param, pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE));
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4");
+ if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
+ {
+#ifdef MAX_RES_1080P
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
+ mp4_param.nBFrames = 1;
+ }
+#else
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
+ mp4_param.nBFrames = 0;
+ }
+#endif
+ }
+ else
+ {
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
+ mp4_param.nBFrames = 0;
+ }
+ }
+ if(handle->venc_set_param(&mp4_param,OMX_IndexParamVideoMpeg4) != true)
+ {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sParamMPEG4,pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE));
+ break;
+ }
+ case OMX_IndexParamVideoH263:
+ {
+ OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263");
+ if(handle->venc_set_param(paramData,OMX_IndexParamVideoH263) != true)
+ {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE));
+ break;
+ }
+ case OMX_IndexParamVideoAvc:
+ {
+ OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
+ OMX_VIDEO_PARAM_AVCTYPE avc_param;
+ memcpy(&avc_param, pParam, sizeof( struct OMX_VIDEO_PARAM_AVCTYPE));
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc");
+
+ if((pParam->eProfile == OMX_VIDEO_AVCProfileHigh)||
+ (pParam->eProfile == OMX_VIDEO_AVCProfileMain))
+ {
+#ifdef MAX_RES_1080P
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
+ avc_param.nBFrames = 1;
+ }
+ if(pParam->nRefFrames != 2)
+ {
+ DEBUG_PRINT_ERROR("Warning: 2 RefFrames are needed, changing RefFrames from %d to 2", pParam->nRefFrames);
+ avc_param.nRefFrames = 2;
+ }
+#else
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
+ avc_param.nBFrames = 0;
+ }
+ if(pParam->nRefFrames != 1)
+ {
+ DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %d to 1)", pParam->nRefFrames);
+ avc_param.nRefFrames = 1;
+ }
+#endif
+ }
+ else
+ {
+ if(pParam->nRefFrames != 1)
+ {
+ DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %d to 1)", pParam->nRefFrames);
+ avc_param.nRefFrames = 1;
+ }
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
+ avc_param.nBFrames = 0;
+ }
+ }
+ if(handle->venc_set_param(&avc_param,OMX_IndexParamVideoAvc) != true)
+ {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sParamAVC,pParam, sizeof(struct OMX_VIDEO_PARAM_AVCTYPE));
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent");
+ if(handle->venc_set_param(pParam,OMX_IndexParamVideoProfileLevelCurrent) != true)
+ {
+ DEBUG_PRINT_ERROR("set_parameter: OMX_IndexParamVideoProfileLevelCurrent failed for Profile: %d "
+ "Level :%d", pParam->eProfile, pParam->eLevel);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_sParamProfileLevel.eProfile = pParam->eProfile;
+ m_sParamProfileLevel.eLevel = pParam->eLevel;
+
+ if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile;
+ m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel;
+ DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile,
+ m_sParamMPEG4.eLevel);
+ }
+ else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile;
+ m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel;
+ DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile,
+ m_sParamH263.eLevel);
+ }
+ else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)m_sParamProfileLevel.eProfile;
+ m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)m_sParamProfileLevel.eLevel;
+ DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile,
+ m_sParamAVC.eLevel);
+ }
+ break;
+ }
+ case OMX_IndexParamStandardComponentRole:
+ {
+ OMX_PARAM_COMPONENTROLETYPE *comp_role;
+ comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
+ comp_role->cRole);
+
+ if((m_state == OMX_StateLoaded)&&
+ !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ {
+ DEBUG_PRINT_LOW("Set Parameter called in valid state");
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if(!strncmp((char*)comp_role->cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE))
+ {
+ strlcpy((char*)m_cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole);
+ eRet =OMX_ErrorUnsupportedSetting;
+ }
+ }
+ else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if(!strncmp((const char*)comp_role->cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
+ {
+ strlcpy((char*)m_cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+ else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if(!strncmp((const char*)comp_role->cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE))
+ {
+ strlcpy((char*)m_cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole);
+ eRet =OMX_ErrorUnsupportedSetting;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s\n", m_nkind);
+ eRet = OMX_ErrorInvalidComponentName;
+ }
+ break;
+ }
+
+ case OMX_IndexParamPriorityMgmt:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt");
+ if(m_state != OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
+ priorityMgmtype->nGroupID);
+
+ DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
+ priorityMgmtype->nGroupPriority);
+
+ m_sPriorityMgmt.nGroupID = priorityMgmtype->nGroupID;
+ m_sPriorityMgmt.nGroupPriority = priorityMgmtype->nGroupPriority;
+
+ break;
+ }
+
+ case OMX_IndexParamCompBufferSupplier:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier");
+ OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
+ bufferSupplierType->eBufferSupplier);
+ if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
+ m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
+
+ else
+
+ eRet = OMX_ErrorBadPortIndex;
+
+ break;
+
+ }
+ case OMX_IndexParamVideoQuantization:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization\n");
+ OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
+ if(session_qp->nPortIndex == PORT_INDEX_OUT)
+ {
+ if(handle->venc_set_param(paramData, OMX_IndexParamVideoQuantization) != true)
+ {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_sSessionQuantization.nQpI = session_qp->nQpI;
+ m_sSessionQuantization.nQpP = session_qp->nQpP;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unsupported port Index for Session QP setting\n");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_QcomIndexPortDefn:
+ {
+ OMX_QCOM_PARAM_PORTDEFINITIONTYPE* pParam =
+ (OMX_QCOM_PARAM_PORTDEFINITIONTYPE*)paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexPortDefn");
+ if(pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN)
+ {
+ if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid &&
+ pParam->nMemRegion < OMX_QCOM_MemRegionMax)
+ {
+ m_use_input_pmem = OMX_TRUE;
+ }
+ else
+ {
+ m_use_input_pmem = OMX_FALSE;
+ }
+ }
+ else if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
+ {
+ if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid &&
+ pParam->nMemRegion < OMX_QCOM_MemRegionMax)
+ {
+ m_use_output_pmem = OMX_TRUE;
+ }
+ else
+ {
+ m_use_output_pmem = OMX_FALSE;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: SetParameter called on unsupported Port Index for QcomPortDefn");
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_IndexParamVideoErrorCorrection:
+ {
+ DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n");
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam =
+ (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
+ if(!handle->venc_set_param(paramData, OMX_IndexParamVideoErrorCorrection))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Error Resilience failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection));
+ break;
+ }
+ case OMX_IndexParamVideoIntraRefresh:
+ {
+ DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh\n");
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam =
+ (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
+ if(!handle->venc_set_param(paramData,OMX_IndexParamVideoIntraRefresh))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra refresh failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh));
+ break;
+ }
+#ifdef _ANDROID_ICS_
+ case OMX_QcomIndexParamVideoEncodeMetaBufferMode:
+ {
+ StoreMetaDataInBuffersParams *pParam =
+ (StoreMetaDataInBuffersParams*)paramData;
+ if(pParam->nPortIndex == PORT_INDEX_IN)
+ {
+ if(pParam->bStoreMetaData != meta_mode_enable)
+ {
+ if(!handle->venc_set_meta_mode(pParam->bStoreMetaData))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: set Metabuffer mode %d fail",
+ pParam->bStoreMetaData);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ meta_mode_enable = pParam->bStoreMetaData;
+ if(meta_mode_enable) {
+ m_sInPortDef.nBufferCountActual = 32;
+ m_sInPortDef.nBufferCountMin = 32;
+ if(handle->venc_set_param(&m_sInPortDef,OMX_IndexParamPortDefinition) != true)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ } else {
+ /*TODO: reset encoder driver Meta mode*/
+ dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ m_sOutPortDef.nPortIndex);
+ }
+ }
+ }
+ break;
+ }
+#endif
+#ifndef MAX_RES_720P
+ case OMX_QcomIndexParamIndexExtraDataType:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamIndexExtraDataType");
+ QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
+ if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo)
+ {
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ if (pParam->bEnabled == OMX_TRUE)
+ m_sExtraData |= VEN_EXTRADATA_SLICEINFO;
+ else
+ m_sExtraData &= ~VEN_EXTRADATA_SLICEINFO;
+ DEBUG_PRINT_HIGH("set_param: m_sExtraData=%x", m_sExtraData);
+ if(handle->venc_set_param(&m_sExtraData,
+ (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) != true)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setting "
+ "OMX_QcomIndexParamIndexExtraDataType failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ else
+ {
+ m_sOutPortDef.nPortIndex = PORT_INDEX_OUT;
+ dev_get_buf_req(&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ m_sOutPortDef.nPortIndex);
+ DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%d, "
+ "count min=%d, buffer size=%d",
+ m_sOutPortDef.nBufferCountActual,
+ m_sOutPortDef.nBufferCountMin,
+ m_sOutPortDef.nBufferSize);
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("set_parameter: slice information is "
+ "valid for output port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("set_parameter: unsupported index (%x), "
+ "only slice information extradata is supported", pParam->nIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ break;
+ }
+#endif
+ case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck:
+ {
+ QOMX_EXTNINDEX_PARAMTYPE* pParam =
+ (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
+ if(pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ handle->m_max_allowed_bitrate_check =
+ ((pParam->bEnable == OMX_TRUE) ? true : false);
+ DEBUG_PRINT_HIGH("set_parameter: max allowed bitrate check %s",
+ ((pParam->bEnable == OMX_TRUE) ? "enabled" : "disabled"));
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexParamVideoMaxAllowedBitrateCheck "
+ " called on wrong port(%d)", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+#ifdef MAX_RES_1080P
+ case OMX_QcomIndexEnableSliceDeliveryMode:
+ {
+ QOMX_EXTNINDEX_PARAMTYPE* pParam =
+ (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
+ if(pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ if(!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode))
+ {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableSliceDeliveryMode "
+ "called on wrong port(%d)", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+#endif
+ case OMX_IndexParamVideoSliceFMO:
+ default:
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d\n", paramIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ }
+ return eRet;
+}
+
+bool omx_venc::update_profile_level()
+{
+ OMX_U32 eProfile, eLevel;
+
+ if(!handle->venc_get_profile_level(&eProfile,&eLevel))
+ {
+ DEBUG_PRINT_ERROR("\nFailed to update the profile_level\n");
+ return false;
+ }
+
+ m_sParamProfileLevel.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile;
+ m_sParamProfileLevel.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel;
+
+ if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile;
+ m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel;
+ DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile,
+ m_sParamMPEG4.eLevel);
+ }
+ else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile;
+ m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel;
+ DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile,
+ m_sParamH263.eLevel);
+ }
+ else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)eProfile;
+ m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)eLevel;
+ DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile,
+ m_sParamAVC.eLevel);
+ }
+ return true;
+}
+/* ======================================================================
+FUNCTION
+ omx_video::SetConfig
+
+DESCRIPTION
+ OMX Set Config method implementation
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+========================================================================== */
+OMX_ERRORTYPE omx_venc::set_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_IN OMX_PTR configData)
+{
+ if(configData == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR: param is null");
+ return OMX_ErrorBadParameter;
+ }
+
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: config called in Invalid state");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ // params will be validated prior to venc_init
+ switch(configIndex)
+ {
+ case OMX_IndexConfigVideoBitrate:
+ {
+ OMX_VIDEO_CONFIG_BITRATETYPE* pParam =
+ reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
+ DEBUG_PRINT_LOW("\n omx_venc:: set_config(): OMX_IndexConfigVideoBitrate");
+
+ if(pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ if(handle->venc_set_config(configData, OMX_IndexConfigVideoBitrate) != true)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoBitrate failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate;
+ m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate;
+ m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ OMX_CONFIG_FRAMERATETYPE* pParam =
+ reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
+ DEBUG_PRINT_LOW("\n omx_venc:: set_config(): OMX_IndexConfigVideoFramerate");
+
+ if(pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ if(handle->venc_set_config(configData, OMX_IndexConfigVideoFramerate) != true)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoFramerate failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate;
+ m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate;
+ m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ QOMX_VIDEO_INTRAPERIODTYPE* pParam =
+ reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
+
+ if(pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+#ifdef MAX_RES_720P
+ if(pParam->nBFrames > 0)
+ {
+ DEBUG_PRINT_ERROR("B frames not supported\n");
+ return OMX_ErrorUnsupportedSetting;
+ }
+#endif
+ if(handle->venc_set_config(configData, (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod) != true)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setting QOMX_IndexConfigVideoIntraperiod failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_sIntraperiod.nPFrames = pParam->nPFrames;
+ m_sIntraperiod.nBFrames = pParam->nBFrames;
+ m_sIntraperiod.nIDRPeriod = pParam->nIDRPeriod;
+
+ if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
+ {
+ m_sParamMPEG4.nPFrames = pParam->nPFrames;
+ if(m_sParamMPEG4.eProfile != OMX_VIDEO_MPEG4ProfileSimple)
+ m_sParamMPEG4.nBFrames = pParam->nBFrames;
+ else
+ m_sParamMPEG4.nBFrames = 0;
+ }
+ else if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingH263)
+ {
+ m_sParamH263.nPFrames = pParam->nPFrames;
+ }
+ else
+ {
+ m_sParamAVC.nPFrames = pParam->nPFrames;
+ if(m_sParamAVC.eProfile != OMX_VIDEO_AVCProfileBaseline)
+ m_sParamAVC.nBFrames = pParam->nBFrames;
+ else
+ m_sParamAVC.nBFrames = 0;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %u", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ {
+ OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam =
+ reinterpret_cast<OMX_CONFIG_INTRAREFRESHVOPTYPE*>(configData);
+
+ if(pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ if(handle->venc_set_config(configData,
+ OMX_IndexConfigVideoIntraVOPRefresh) != true)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoIntraVOPRefresh failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+ case OMX_IndexConfigCommonRotate:
+ {
+ OMX_CONFIG_ROTATIONTYPE *pParam =
+ reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
+ OMX_S32 nRotation;
+
+ if(pParam->nPortIndex != PORT_INDEX_IN){
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ if( pParam->nRotation == 0 ||
+ pParam->nRotation == 90 ||
+ pParam->nRotation == 180 ||
+ pParam->nRotation == 270 ) {
+ DEBUG_PRINT_HIGH("\nset_config: Rotation Angle %u", pParam->nRotation);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: un supported Rotation %u", pParam->nRotation);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ nRotation = pParam->nRotation - m_sConfigFrameRotation.nRotation;
+ if(nRotation < 0)
+ nRotation = -nRotation;
+ if(nRotation == 90 || nRotation == 270) {
+ DEBUG_PRINT_HIGH("\nset_config: updating device Dims");
+ if(handle->venc_set_config(configData,
+ OMX_IndexConfigCommonRotate) != true) {
+ DEBUG_PRINT_ERROR("ERROR: Set OMX_IndexConfigCommonRotate failed");
+ return OMX_ErrorUnsupportedSetting;
+ } else {
+ OMX_U32 nFrameWidth;
+
+ DEBUG_PRINT_HIGH("\nset_config: updating port Dims");
+
+ nFrameWidth = m_sInPortDef.format.video.nFrameWidth;
+ m_sInPortDef.format.video.nFrameWidth =
+ m_sInPortDef.format.video.nFrameHeight;
+ m_sInPortDef.format.video.nFrameHeight = nFrameWidth;
+
+ m_sOutPortDef.format.video.nFrameWidth =
+ m_sInPortDef.format.video.nFrameWidth;
+ m_sOutPortDef.format.video.nFrameHeight =
+ m_sInPortDef.format.video.nFrameHeight;
+ m_sConfigFrameRotation.nRotation = pParam->nRotation;
+ }
+ } else {
+ m_sConfigFrameRotation.nRotation = pParam->nRotation;
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigVideoFramePackingArrangement:
+ {
+ if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingAVC)
+ {
+ OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
+ (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
+ extra_data_handle.set_frame_pack_data(configFmt);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: FramePackingData not supported for non AVC compression");
+ }
+ break;
+ }
+ default:
+ DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
+ break;
+ }
+
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_venc::ComponentDeInit
+
+DESCRIPTION
+ Destroys the component and release memory allocated to the heap.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+ OMX_U32 i = 0;
+ DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_deinit()");
+ if(OMX_StateLoaded != m_state)
+ {
+ DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
+ m_state);
+ }
+ if(m_out_mem_ptr)
+ {
+ DEBUG_PRINT_LOW("Freeing the Output Memory\n");
+ for(i=0; i< m_sOutPortDef.nBufferCountActual; i++ )
+ {
+ free_output_buffer (&m_out_mem_ptr[i]);
+ }
+ free(m_out_mem_ptr);
+ m_out_mem_ptr = NULL;
+ }
+
+ /*Check if the input buffers have to be cleaned up*/
+ if(m_inp_mem_ptr
+#ifdef _ANDROID_ICS_
+ && !meta_mode_enable
+#endif
+ )
+ {
+ DEBUG_PRINT_LOW("Freeing the Input Memory\n");
+ for(i=0; i<m_sInPortDef.nBufferCountActual; i++ )
+ {
+ free_input_buffer (&m_inp_mem_ptr[i]);
+ }
+
+
+ free(m_inp_mem_ptr);
+ m_inp_mem_ptr = NULL;
+ }
+
+ // Reset counters in mesg queues
+ m_ftb_q.m_size=0;
+ m_cmd_q.m_size=0;
+ m_etb_q.m_size=0;
+ m_ftb_q.m_read = m_ftb_q.m_write =0;
+ m_cmd_q.m_read = m_cmd_q.m_write =0;
+ m_etb_q.m_read = m_etb_q.m_write =0;
+
+#ifdef _ANDROID_
+ // Clear the strong reference
+ DEBUG_PRINT_HIGH("Calling m_heap_ptr.clear()\n");
+ m_heap_ptr.clear();
+#endif // _ANDROID_
+ DEBUG_PRINT_HIGH("Calling venc_close()\n");
+ handle->venc_close();
+ DEBUG_PRINT_HIGH("Deleting HANDLE[%p]\n", handle);
+ delete (handle);
+ DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit\n");
+ return OMX_ErrorNone;
+}
+
+
+OMX_U32 omx_venc::dev_stop( void)
+{
+ return handle->venc_stop();
+}
+
+
+OMX_U32 omx_venc::dev_pause(void)
+{
+ return handle->venc_pause();
+}
+
+OMX_U32 omx_venc::dev_start(void)
+{
+ return handle->venc_start();
+}
+
+OMX_U32 omx_venc::dev_flush(unsigned port)
+{
+ return handle->venc_flush(port);
+}
+OMX_U32 omx_venc::dev_resume(void)
+{
+ return handle->venc_resume();
+}
+
+OMX_U32 omx_venc::dev_start_done(void)
+{
+ return handle->venc_start_done();
+}
+
+OMX_U32 omx_venc::dev_stop_done(void)
+{
+ return handle->venc_stop_done();
+}
+
+bool omx_venc::dev_use_buf(void *buf_addr,unsigned port,unsigned index)
+{
+ return handle->venc_use_buf(buf_addr,port,index);
+}
+
+bool omx_venc::dev_free_buf(void *buf_addr,unsigned port)
+{
+ return handle->venc_free_buf(buf_addr,port);
+}
+
+bool omx_venc::dev_empty_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
+{
+ return handle->venc_empty_buf(buffer, pmem_data_buf,index,fd);
+}
+
+bool omx_venc::dev_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
+{
+ return handle->venc_fill_buf(buffer, pmem_data_buf,index,fd);
+}
+
+bool omx_venc::dev_get_seq_hdr(void *buffer, unsigned size, unsigned *hdrlen)
+{
+ return handle->venc_get_seq_hdr(buffer, size, hdrlen);
+}
+
+bool omx_venc::dev_loaded_start()
+{
+ return handle->venc_loaded_start();
+}
+
+bool omx_venc::dev_loaded_stop()
+{
+ return handle->venc_loaded_stop();
+}
+
+bool omx_venc::dev_loaded_start_done()
+{
+ return handle->venc_loaded_start_done();
+}
+
+bool omx_venc::dev_loaded_stop_done()
+{
+ return handle->venc_loaded_stop_done();
+}
+
+bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count,
+ OMX_U32 *actual_buff_count,
+ OMX_U32 *buff_size,
+ OMX_U32 port)
+{
+ return handle->venc_get_buf_req(min_buff_count,
+ actual_buff_count,
+ buff_size,
+ port);
+
+}
+
+bool omx_venc::dev_set_buf_req(OMX_U32 *min_buff_count,
+ OMX_U32 *actual_buff_count,
+ OMX_U32 *buff_size,
+ OMX_U32 port)
+{
+ return handle->venc_set_buf_req(min_buff_count,
+ actual_buff_count,
+ buff_size,
+ port);
+
+}
+
+int omx_venc::async_message_process (void *context, void* message)
+{
+ omx_video* omx = NULL;
+ struct venc_msg *m_sVenc_msg = NULL;
+ OMX_BUFFERHEADERTYPE* omxhdr = NULL;
+ struct venc_buffer *temp_buff = NULL;
+
+ if(context == NULL || message == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: omx_venc::async_message_process invalid i/p params");
+ return -1;
+ }
+ m_sVenc_msg = (struct venc_msg *)message;
+
+ omx = reinterpret_cast<omx_video*>(context);
+
+ if(m_sVenc_msg->statuscode != VEN_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: async_msg_process() - Error statuscode = %d\n",
+ m_sVenc_msg->statuscode);
+ omx->omx_report_error();
+ }
+
+ DEBUG_PRINT_LOW("\n omx_venc::async_message_process- msgcode = %d\n",
+ m_sVenc_msg->msgcode);
+ switch(m_sVenc_msg->msgcode)
+ {
+
+ case VEN_MSG_START:
+ omx->post_event (NULL,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_START_DONE);
+ break;
+
+ case VEN_MSG_STOP:
+ omx->post_event (NULL,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_STOP_DONE);
+ break;
+
+ case VEN_MSG_RESUME:
+ omx->post_event (NULL,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_RESUME_DONE);
+ break;
+
+ case VEN_MSG_PAUSE:
+ omx->post_event (NULL,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_PAUSE_DONE);
+
+ break;
+
+ case VEN_MSG_FLUSH_INPUT_DONE:
+
+ omx->post_event (NULL,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
+ break;
+ case VEN_MSG_FLUSH_OUPUT_DONE:
+ omx->post_event (NULL,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
+ break;
+ case VEN_MSG_INPUT_BUFFER_DONE:
+ omxhdr = (OMX_BUFFERHEADERTYPE* )\
+ m_sVenc_msg->buf.clientdata;
+
+ if(omxhdr == NULL ||
+ ((OMX_U32)(omxhdr - omx->m_inp_mem_ptr) > omx->m_sInPortDef.nBufferCountActual) )
+ {
+ omxhdr = NULL;
+ m_sVenc_msg->statuscode = VEN_S_EFAIL;
+ }
+#ifdef _ANDROID_ICS_
+ omx->omx_release_meta_buffer(omxhdr);
+#endif
+ omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode,
+ OMX_COMPONENT_GENERATE_EBD);
+ break;
+ case VEN_MSG_OUTPUT_BUFFER_DONE:
+
+ omxhdr = (OMX_BUFFERHEADERTYPE*)m_sVenc_msg->buf.clientdata;
+
+ if( (omxhdr != NULL) &&
+ ((OMX_U32)(omxhdr - omx->m_out_mem_ptr) < omx->m_sOutPortDef.nBufferCountActual))
+ {
+ if(m_sVenc_msg->buf.len <= omxhdr->nAllocLen)
+ {
+ omxhdr->nFilledLen = m_sVenc_msg->buf.len;
+ omxhdr->nOffset = m_sVenc_msg->buf.offset;
+ omxhdr->nTimeStamp = m_sVenc_msg->buf.timestamp;
+ DEBUG_PRINT_LOW("\n o/p TS = %u", (OMX_U32)m_sVenc_msg->buf.timestamp);
+ omxhdr->nFlags = m_sVenc_msg->buf.flags;
+
+ /*Use buffer case*/
+ if(omx->output_use_buffer && !omx->m_use_output_pmem)
+ {
+ DEBUG_PRINT_LOW("\n memcpy() for o/p Heap UseBuffer");
+ memcpy(omxhdr->pBuffer,
+ (m_sVenc_msg->buf.ptrbuffer),
+ m_sVenc_msg->buf.len);
+ }
+ }
+ else
+ {
+ omxhdr->nFilledLen = 0;
+ }
+
+ }
+ else
+ {
+ omxhdr = NULL;
+ m_sVenc_msg->statuscode = VEN_S_EFAIL;
+ }
+
+ omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode,
+ OMX_COMPONENT_GENERATE_FBD);
+ break;
+ case VEN_MSG_NEED_OUTPUT_BUFFER:
+ //TBD what action needs to be done here??
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/mm-video/vidc/venc/src/video_encoder_device.cpp b/mm-video/vidc/venc/src/video_encoder_device.cpp
new file mode 100755
index 0000000..6e9b63c
--- /dev/null
+++ b/mm-video/vidc/venc/src/video_encoder_device.cpp
@@ -0,0 +1,2935 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#include<string.h>
+#include <sys/ioctl.h>
+#include <sys/prctl.h>
+#include<unistd.h>
+#include <fcntl.h>
+#include "video_encoder_device.h"
+#include "omx_video_encoder.h"
+#include <linux/android_pmem.h>
+#ifdef USE_ION
+#include <ion_msm.h>
+#endif
+
+#define MPEG4_SP_START 0
+#define MPEG4_ASP_START (MPEG4_SP_START + 8)
+#define MPEG4_720P_LEVEL 6
+#define H263_BP_START 0
+#define H264_BP_START 0
+#define H264_HP_START (H264_BP_START + 13)
+#define H264_MP_START (H264_BP_START + 26)
+
+/* MPEG4 profile and level table*/
+static const unsigned int mpeg4_profile_level_table[][5]=
+{
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
+ {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
+ {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
+ {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
+ {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
+ {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
+ {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
+ {0,0,0,0,0},
+
+ {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {0,0,0,0,0},
+};
+
+/* H264 profile and level table*/
+static const unsigned int h264_profile_level_table[][5]=
+{
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
+ {0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
+ {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
+ {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
+ {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
+ {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
+ {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
+ {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
+ {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
+ {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
+ {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
+ {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
+ {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
+ {0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
+ {0,0,0,0,0}
+
+};
+
+/* H263 profile and level table*/
+static const unsigned int h263_profile_level_table[][5]=
+{
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
+ {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
+ {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
+ {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
+ {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
+ {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
+ {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
+ {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
+ {0,0,0,0,0}
+};
+
+#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
+#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
+
+#ifdef INPUT_BUFFER_LOG
+FILE *inputBufferFile1;
+char inputfilename [] = "/data/input.yuv";
+#endif
+#ifdef OUTPUT_BUFFER_LOG
+FILE *outputBufferFile1;
+char outputfilename [] = "/data/output-bitstream.\0\0\0\0";
+#endif
+//constructor
+venc_dev::venc_dev(class omx_venc *venc_class)
+{
+ m_max_allowed_bitrate_check = false;
+ m_eLevel = 0;
+ m_eProfile = 0;
+ pthread_mutex_init(&loaded_start_stop_mlock, NULL);
+ pthread_cond_init (&loaded_start_stop_cond, NULL);
+ DEBUG_PRINT_LOW("venc_dev constructor");
+}
+
+venc_dev::~venc_dev()
+{
+ pthread_cond_destroy(&loaded_start_stop_cond);
+ pthread_mutex_destroy(&loaded_start_stop_mlock);
+ DEBUG_PRINT_LOW("venc_dev distructor");
+}
+
+void* async_venc_message_thread (void *input)
+{
+ struct venc_ioctl_msg ioctl_msg ={NULL,NULL};
+ struct venc_timeout timeout;
+ struct venc_msg venc_msg;
+ int error_code = 0;
+ omx_venc *omx = reinterpret_cast<omx_venc*>(input);
+
+ prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
+ timeout.millisec = VEN_TIMEOUT_INFINITE;
+ while(1)
+ {
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&venc_msg;
+
+ /*Wait for a message from the video decoder driver*/
+ error_code = ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg);
+ if (error_code == -512) // ERESTARTSYS
+ {
+ DEBUG_PRINT_ERROR("\n ERESTARTSYS received in ioctl read next msg!");
+ }
+ else if (error_code <0)
+ {
+ DEBUG_PRINT_ERROR("\nioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed");
+ break;
+ }
+ else if(omx->async_message_process(input,&venc_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
+ break;
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n");
+ return NULL;
+}
+
+bool venc_dev::venc_open(OMX_U32 codec)
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ int r;
+ unsigned int alignment = 0,buffer_size = 0, temp =0;
+
+ m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK);
+ if(m_nDriver_fd == 0)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n");
+ m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK);
+ }
+
+ if((int)m_nDriver_fd < 0)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd);
+#ifdef SINGLE_ENCODER_INSTANCE
+ OMX_U32 num_instances = 0;
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = &num_instances;
+ if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_NUMBER_INSTANCES, (void*)&ioctl_msg) < 0 )
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request number of encoder instances failed");
+ }
+ else if (num_instances > 1)
+ {
+ DEBUG_PRINT_ERROR("\nSecond encoder instance rejected!");
+ venc_close();
+ return false;
+ }
+#endif
+ // set the basic configuration of the video encoder driver
+ m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
+ m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
+ m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
+ m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
+ m_sVenc_cfg.fps_num = 30;
+ m_sVenc_cfg.fps_den = 1;
+ m_sVenc_cfg.targetbitrate = 64000;
+#ifdef MAX_RES_1080P
+ m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
+#else
+ m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12;
+#endif
+ if(codec == OMX_VIDEO_CodingMPEG4)
+ {
+ m_sVenc_cfg.codectype = VEN_CODEC_MPEG4;
+ codec_profile.profile = VEN_PROFILE_MPEG4_SP;
+ profile_level.level = VEN_LEVEL_MPEG4_2;
+#ifdef OUTPUT_BUFFER_LOG
+ strcat(outputfilename, "m4v");
+#endif
+ }
+ else if(codec == OMX_VIDEO_CodingH263)
+ {
+ m_sVenc_cfg.codectype = VEN_CODEC_H263;
+ codec_profile.profile = VEN_PROFILE_H263_BASELINE;
+ profile_level.level = VEN_LEVEL_H263_20;
+#ifdef OUTPUT_BUFFER_LOG
+ strcat(outputfilename, "263");
+#endif
+ }
+ if(codec == OMX_VIDEO_CodingAVC)
+ {
+ m_sVenc_cfg.codectype = VEN_CODEC_H264;
+ codec_profile.profile = VEN_PROFILE_H264_BASELINE;
+ profile_level.level = VEN_LEVEL_H264_1p1;
+#ifdef OUTPUT_BUFFER_LOG
+ strcat(outputfilename, "264");
+#endif
+ }
+ ioctl_msg.in = (void*)&m_sVenc_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 )
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting base configuration failed");
+ return false;
+ }
+#ifdef INPUT_BUFFER_LOG
+ inputBufferFile1 = fopen (inputfilename, "ab");
+#endif
+#ifdef OUTPUT_BUFFER_LOG
+ outputBufferFile1 = fopen (outputfilename, "ab");
+#endif
+ // Get the I/P and O/P buffer requirements
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&m_sInput_buff_property;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
+ return false;
+ }
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&m_sOutput_buff_property;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
+ return false;
+ }
+
+ m_profile_set = false;
+ m_level_set = false;
+ if(venc_set_profile_level(0, 0))
+ {
+ DEBUG_PRINT_HIGH("\n %s(): Init Profile/Level setting success",
+ __func__);
+ }
+ recon_buffers_count = MAX_RECON_BUFFERS;
+ return true;
+}
+
+void venc_dev::venc_close()
+{
+ DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd);
+ if((int)m_nDriver_fd >= 0)
+ {
+ DEBUG_PRINT_HIGH("\n venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG");
+ (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG,
+ NULL);
+ DEBUG_PRINT_LOW("\nCalling close()\n");
+ close(m_nDriver_fd);
+ m_nDriver_fd = -1;
+ }
+#ifdef INPUT_BUFFER_LOG
+ fclose (inputBufferFile1);
+#endif
+#ifdef OUTPUT_BUFFER_LOG
+ fclose (outputBufferFile1);
+#endif
+}
+
+bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count,
+ unsigned long *actual_buff_count,
+ unsigned long *buff_size,
+ unsigned long port)
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ unsigned long temp_count = 0;
+
+ if(port == 0)
+ {
+ if(*actual_buff_count > m_sInput_buff_property.mincount)
+ {
+ temp_count = m_sInput_buff_property.actualcount;
+ m_sInput_buff_property.actualcount = *actual_buff_count;
+ ioctl_msg.in = (void*)&m_sInput_buff_property;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirement failed");
+ m_sInput_buff_property.actualcount = temp_count;
+ return false;
+ }
+ DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count);
+ }
+ }
+ else
+ {
+ if(*actual_buff_count > m_sOutput_buff_property.mincount)
+ {
+ temp_count = m_sOutput_buff_property.actualcount;
+ m_sOutput_buff_property.actualcount = *actual_buff_count;
+ ioctl_msg.in = (void*)&m_sOutput_buff_property;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer requirement failed");
+ m_sOutput_buff_property.actualcount = temp_count;
+ return false;
+ }
+ DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count);
+ }
+ }
+
+ return true;
+
+}
+
+bool venc_dev::venc_loaded_start()
+{
+ struct timespec ts;
+ int status = 0;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_START, NULL) < 0)
+ {
+ DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_START failed");
+ return false;
+ }
+ if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
+ {
+ DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
+ return false;
+ }
+ ts.tv_sec += 1;
+ pthread_mutex_lock(&loaded_start_stop_mlock);
+ DEBUG_PRINT_LOW("%s: wait on start done", __func__);
+ status = pthread_cond_timedwait(&loaded_start_stop_cond,
+ &loaded_start_stop_mlock, &ts);
+ if (status != 0)
+ {
+ DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
+ status, strerror(status));
+ pthread_mutex_unlock(&loaded_start_stop_mlock);
+ return false;
+ }
+ DEBUG_PRINT_LOW("%s: wait over on start done", __func__);
+ pthread_mutex_unlock(&loaded_start_stop_mlock);
+ DEBUG_PRINT_LOW("%s: venc_loaded_start success", __func__);
+ return true;
+}
+
+bool venc_dev::venc_loaded_stop()
+{
+ struct timespec ts;
+ int status = 0;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_STOP, NULL) < 0)
+ {
+ DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_STOP failed");
+ return false;
+ }
+ if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
+ {
+ DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
+ return false;
+ }
+ ts.tv_sec += 1;
+ pthread_mutex_lock(&loaded_start_stop_mlock);
+ DEBUG_PRINT_LOW("%s: wait on stop done", __func__);
+ status = pthread_cond_timedwait(&loaded_start_stop_cond,
+ &loaded_start_stop_mlock, &ts);
+ if (status != 0)
+ {
+ DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
+ status, strerror(status));
+ pthread_mutex_unlock(&loaded_start_stop_mlock);
+ return false;
+ }
+ DEBUG_PRINT_LOW("%s: wait over on stop done", __func__);
+ pthread_mutex_unlock(&loaded_start_stop_mlock);
+ DEBUG_PRINT_LOW("%s: venc_loaded_stop success", __func__);
+ return true;
+}
+
+bool venc_dev::venc_loaded_start_done()
+{
+ pthread_mutex_lock(&loaded_start_stop_mlock);
+ DEBUG_PRINT_LOW("%s: signal start done", __func__);
+ pthread_cond_signal(&loaded_start_stop_cond);
+ pthread_mutex_unlock(&loaded_start_stop_mlock);
+ return true;
+}
+
+bool venc_dev::venc_loaded_stop_done()
+{
+ pthread_mutex_lock(&loaded_start_stop_mlock);
+ DEBUG_PRINT_LOW("%s: signal stop done", __func__);
+ pthread_cond_signal(&loaded_start_stop_cond);
+ pthread_mutex_unlock(&loaded_start_stop_mlock);
+ return true;
+}
+
+bool venc_dev::venc_get_seq_hdr(void *buffer,
+ unsigned buffer_size, unsigned *header_len)
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ int i = 0;
+ DEBUG_PRINT_HIGH("venc_dev::venc_get_seq_hdr");
+ venc_seqheader seq_in, seq_out;
+ seq_in.hdrlen = 0;
+ seq_in.bufsize = buffer_size;
+ seq_in.hdrbufptr = (unsigned char*)buffer;
+ if (seq_in.hdrbufptr == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: malloc for sequence header failed");
+ return false;
+ }
+ DEBUG_PRINT_LOW("seq_in: buf=%x, sz=%d, hdrlen=%d", seq_in.hdrbufptr,
+ seq_in.bufsize, seq_in.hdrlen);
+
+ ioctl_msg.in = (void*)&seq_in;
+ ioctl_msg.out = (void*)&seq_out;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_SEQUENCE_HDR,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Request for getting sequence header failed");
+ return false;
+ }
+ if (seq_out.hdrlen == 0) {
+ DEBUG_PRINT_ERROR("ERROR: Seq header returned zero length header");
+ DEBUG_PRINT_ERROR("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
+ seq_out.bufsize, seq_out.hdrlen);
+ return false;
+ }
+ *header_len = seq_out.hdrlen;
+ DEBUG_PRINT_LOW("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
+ seq_out.bufsize, seq_out.hdrlen);
+
+ return true;
+}
+
+bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count,
+ unsigned long *actual_buff_count,
+ unsigned long *buff_size,
+ unsigned long port)
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+
+ if(port == 0)
+ {
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&m_sInput_buff_property;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
+ return false;
+ }
+ *min_buff_count = m_sInput_buff_property.mincount;
+ *actual_buff_count = m_sInput_buff_property.actualcount;
+#ifdef USE_ION
+ // For ION memory allocations of the allocated buffer size
+ // must be 4k aligned, hence aligning the input buffer
+ // size to 4k.
+ m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095)
+ & (~4095);
+#endif
+ *buff_size = m_sInput_buff_property.datasize;
+ }
+ else
+ {
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&m_sOutput_buff_property;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
+ return false;
+ }
+ *min_buff_count = m_sOutput_buff_property.mincount;
+ *actual_buff_count = m_sOutput_buff_property.actualcount;
+ *buff_size = m_sOutput_buff_property.datasize;
+ }
+
+ return true;
+
+}
+
+bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n");
+ switch(index)
+ {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition\n");
+ if(portDefn->nPortIndex == PORT_INDEX_IN)
+ {
+
+ if(!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0))
+ {
+ return false;
+ }
+
+ if(!venc_set_color_format(portDefn->format.video.eColorFormat))
+ {
+ return false;
+ }
+ if(m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
+ m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth)
+ {
+ DEBUG_PRINT_LOW("\n Basic parameter has changed");
+ m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
+ m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
+
+ ioctl_msg.in = (void*)&m_sVenc_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting base config failed");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("\n Updating the buffer count/size for the new resolution");
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&m_sInput_buff_property;
+ if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p bufreq failed");
+ return false;
+ }
+ DEBUG_PRINT_LOW("\n Got updated m_sInput_buff_property values: "
+ "datasize = %u, maxcount = %u, actualcnt = %u, "
+ "mincount = %u", m_sInput_buff_property.datasize,
+ m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount,
+ m_sInput_buff_property.mincount);
+
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&m_sOutput_buff_property;
+ if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p bufreq failed");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("\n Got updated m_sOutput_buff_property values: "
+ "datasize = %u, maxcount = %u, actualcnt = %u, "
+ "mincount = %u", m_sOutput_buff_property.datasize,
+ m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount,
+ m_sOutput_buff_property.mincount);
+ ioctl_msg.in = (void*)&m_sOutput_buff_property;
+ ioctl_msg.out = NULL;
+
+ if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p bufreq failed");
+ return false;
+ }
+
+ if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
+ (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount))
+ {
+ m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
+ ioctl_msg.in = (void*)&m_sInput_buff_property;
+ ioctl_msg.out = NULL;
+ if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirements failed");
+ return false;
+ }
+ }
+ if(m_sInput_buff_property.datasize != portDefn->nBufferSize)
+ {
+ DEBUG_PRINT_ERROR("\nWARNING: Requested i/p bufsize[%u],"
+ "Driver's updated i/p bufsize = %u", portDefn->nBufferSize,
+ m_sInput_buff_property.datasize);
+ }
+ m_level_set = false;
+ if(venc_set_profile_level(0, 0))
+ {
+ DEBUG_PRINT_HIGH("\n %s(): Profile/Level setting success", __func__);
+ }
+ }
+ else
+ {
+ if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
+ (m_sInput_buff_property.maxcount >= portDefn->nBufferCountActual) &&
+ (m_sInput_buff_property.datasize == portDefn->nBufferSize))
+ {
+ m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
+ ioctl_msg.in = (void*)&m_sInput_buff_property;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_INPUT_BUFFER_REQ failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Input buffer requirements failed");
+ return false;
+ }
+ }
+ }
+ else if(portDefn->nPortIndex == PORT_INDEX_OUT)
+ {
+ if(!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0))
+ {
+ return false;
+ }
+
+ if( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
+ &&
+ (m_sOutput_buff_property.maxcount >= portDefn->nBufferCountActual)
+ &&
+ (m_sOutput_buff_property.datasize == portDefn->nBufferSize)
+ )
+ {
+ m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
+ ioctl_msg.in = (void*)&m_sOutput_buff_property;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
+ portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n");
+
+ if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
+ {
+ if(!venc_set_color_format(portFmt->eColorFormat))
+ {
+ return false;
+ }
+ }
+ else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(!venc_set_encode_framerate(portFmt->xFramerate, 0))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoBitrate:
+ {
+ OMX_VIDEO_PARAM_BITRATETYPE* pParam;
+ pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n");
+
+ if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(!venc_set_target_bitrate(pParam->nTargetBitrate, 0))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed");
+ return false;
+ }
+ if(!venc_set_ratectrl_cfg(pParam->eControlRate))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4:
+ {
+ OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
+ OMX_U32 bFrames = 0;
+
+ pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n");
+ if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(!venc_set_voptiming_cfg(pParam->nTimeIncRes))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed");
+ return false;
+ }
+ m_profile_set = false;
+ m_level_set = false;
+ if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
+ return false;
+ }
+#ifdef MAX_RES_1080P
+ else {
+ if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
+ {
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
+ bFrames = 1;
+ }
+ }
+ else
+ {
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
+ bFrames = 0;
+ }
+ }
+ }
+#endif
+ if(!venc_set_intra_period (pParam->nPFrames,bFrames))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+ if(!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoH263:
+ {
+ OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n");
+ OMX_U32 bFrames = 0;
+ if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ m_profile_set = false;
+ m_level_set = false;
+ if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
+ return false;
+ }
+ if (pParam->nBFrames)
+ DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263");
+
+ if(venc_set_intra_period (pParam->nPFrames, bFrames) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoAvc:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n");
+ OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
+ OMX_U32 bFrames = 0;
+
+ if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n",
+ pParam->eProfile,pParam->eLevel);
+
+ m_profile_set = false;
+ m_level_set = false;
+
+ if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d",
+ pParam->eProfile, pParam->eLevel);
+ return false;
+ }
+#ifdef MAX_RES_1080P
+ else {
+ if(pParam->eProfile != OMX_VIDEO_AVCProfileBaseline)
+ {
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
+ bFrames = 1;
+ }
+ }
+ else
+ {
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
+ bFrames = 0;
+ }
+ }
+ }
+#endif
+ if(!venc_set_intra_period (pParam->nPFrames, bFrames))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+ if(!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed");
+ return false;
+ }
+ if(!venc_set_inloop_filter (pParam->eLoopFilterMode))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed");
+ return false;
+ }
+ if(!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing))
+ {
+ DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
+ }
+ //TBD, lot of other variables to be updated, yet to decide
+ break;
+ }
+ case OMX_IndexParamVideoIntraRefresh:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n");
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
+ (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
+ if(intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoErrorCorrection:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n");
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
+ (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
+ if(error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(venc_set_error_resilience(error_resilience) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n");
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
+ (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
+ if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ m_profile_set = false;
+ m_level_set = false;
+ if(!venc_set_profile_level (profile_level->eProfile,
+ profile_level->eLevel))
+ {
+ DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoQuantization:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n");
+ OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
+ (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
+ if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(venc_set_session_qp (session_qp->nQpI,
+ session_qp->nQpP) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
+ }
+ break;
+ }
+ case OMX_ExtraDataVideoEncoderSliceInfo:
+ {
+ DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
+ OMX_U32 extra_data = *(OMX_U32 *)paramData;
+ if(venc_set_extradata(extra_data) == false)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setting "
+ "OMX_QcomIndexParamIndexExtraDataType failed");
+ return false;
+ }
+ break;
+ }
+ case OMX_QcomIndexEnableSliceDeliveryMode:
+ {
+ QOMX_EXTNINDEX_PARAMTYPE* pParam =
+ (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
+ if(pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ if(venc_set_slice_delivery_mode(pParam->bEnable) == false)
+ {
+ DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
+ "called on wrong port(%d)", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_IndexParamVideoSliceFMO:
+ default:
+ DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u",
+ index);
+ break;
+ //case
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ DEBUG_PRINT_LOW("\n Inside venc_set_config");
+
+ switch(index)
+ {
+ case OMX_IndexConfigVideoBitrate:
+ {
+ OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
+ configData;
+ if(m_max_allowed_bitrate_check &&
+ !venc_max_allowed_bitrate_check(bit_rate->nEncodeBitrate))
+ {
+ DEBUG_PRINT_ERROR("Max Allowed Bitrate Check failed");
+ return false;
+ }
+ DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate");
+ if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
+ {
+ if(venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
+ configData;
+ DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate");
+ if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
+ {
+ if(venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
+ }
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n");
+ QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
+ (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
+ if(intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ {
+ OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
+ configData;
+ DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
+ if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
+ {
+ if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
+ }
+ break;
+ }
+ case OMX_IndexConfigCommonRotate:
+ {
+ OMX_CONFIG_ROTATIONTYPE *config_rotation =
+ reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ OMX_U32 nFrameWidth;
+
+ DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims");
+ nFrameWidth = m_sVenc_cfg.input_width;
+ m_sVenc_cfg.input_width = m_sVenc_cfg.input_height;
+ m_sVenc_cfg.input_height = nFrameWidth;
+ ioctl_msg.in = (void*)&m_sVenc_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) {
+ DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed");
+ return false;
+ }
+ break;
+ }
+ default:
+ DEBUG_PRINT_ERROR("\n Unsupported config index = %u", index);
+ break;
+ }
+
+ return true;
+}
+
+unsigned venc_dev::venc_stop( void)
+{
+#ifdef MAX_RES_1080P
+ pmem_free();
+#endif
+ return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL);
+}
+
+unsigned venc_dev::venc_pause(void)
+{
+ return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL);
+}
+
+unsigned venc_dev::venc_resume(void)
+{
+ return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ;
+}
+
+unsigned venc_dev::venc_start_done(void)
+{
+ return 0;
+}
+
+unsigned venc_dev::venc_stop_done(void)
+{
+ return 0;
+}
+
+unsigned venc_dev::venc_start(void)
+{
+ DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start",
+ __func__);
+ if (!venc_set_profile_level(0, 0))
+ {
+ DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET",
+ __func__);
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET",
+ __func__, codec_profile.profile, profile_level.level);
+ }
+
+ if(m_max_allowed_bitrate_check &&
+ !venc_max_allowed_bitrate_check(bitrate.target_bitrate))
+ {
+ DEBUG_PRINT_ERROR("Maximum Allowed Bitrate Check failed");
+ return -1;
+ }
+
+ venc_config_print();
+
+#ifdef MAX_RES_1080P
+ if((codec_profile.profile == VEN_PROFILE_MPEG4_SP) ||
+ (codec_profile.profile == VEN_PROFILE_H264_BASELINE) ||
+ (codec_profile.profile == VEN_PROFILE_H263_BASELINE))
+ recon_buffers_count = MAX_RECON_BUFFERS - 2;
+ else
+ recon_buffers_count = MAX_RECON_BUFFERS;
+
+ if (!venc_allocate_recon_buffers())
+ return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
+ else
+ {
+ DEBUG_PRINT_ERROR("Failed in creating Recon buffers\n");
+ return -1;
+ }
+#else
+ return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
+#endif
+}
+
+#ifdef MAX_RES_1080P
+OMX_U32 venc_dev::venc_allocate_recon_buffers()
+{
+ OMX_U32 yuv_size;
+ struct venc_ioctl_msg ioctl_msg;
+ struct venc_recon_buff_size recon_buff_size;
+
+ recon_buff_size.width = ((m_sVenc_cfg.input_width + 15) / 16) * 16;
+ recon_buff_size.height = ((m_sVenc_cfg.input_height + 15) / 16 ) * 16;
+
+ DEBUG_PRINT_LOW("Width %d, Height %d, w_round %d, h_round %d\n", m_sVenc_cfg.input_width,
+ m_sVenc_cfg.input_height, recon_buff_size.width, recon_buff_size.height);
+
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&recon_buff_size;
+
+ if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_RECON_BUFFER_SIZE, (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\n VEN_IOCTL_GET_RECON_BUFFER_SIZE Failed for width: %d, Height %d" ,
+ recon_buff_size.width, recon_buff_size.height);
+ return OMX_ErrorInsufficientResources;
+ }
+
+ DEBUG_PRINT_HIGH("Width %d, Height %d, w_round %d, h_round %d, yuv_size %d alignment %d count %d\n",
+ m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, recon_buff_size.width,
+ recon_buff_size.height, recon_buff_size.size, recon_buff_size.alignment,
+ recon_buffers_count);
+
+ for(int i = 0; i < recon_buffers_count; i++)
+ {
+ if(pmem_allocate(recon_buff_size.size, recon_buff_size.alignment,i))
+ {
+ DEBUG_PRINT_ERROR("Error returned in allocating recon buffers\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+OMX_U32 venc_dev::pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count)
+{
+ OMX_U32 pmem_fd = -1;
+ OMX_U32 width, height;
+ void *buf_addr = NULL;
+ struct venc_ioctl_msg ioctl_msg;
+ struct venc_recon_addr recon_addr;
+ int rc = 0;
+
+#ifdef USE_ION
+ recon_buff[count].ion_device_fd = open (MEM_DEVICE,O_RDONLY);
+ if(recon_buff[count].ion_device_fd < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
+ return -1;
+ }
+
+ recon_buff[count].alloc_data.len = size;
+ recon_buff[count].alloc_data.flags = (ION_HEAP(MEM_HEAP_ID) |
+ ION_HEAP(ION_IOMMU_HEAP_ID));
+ recon_buff[count].alloc_data.align = clip2(alignment);
+ if (recon_buff[count].alloc_data.align != 8192)
+ recon_buff[count].alloc_data.align = 8192;
+
+ rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_ALLOC,&recon_buff[count].alloc_data);
+ if(rc || !recon_buff[count].alloc_data.handle) {
+ DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
+ recon_buff[count].alloc_data.handle=NULL;
+ return -1;
+ }
+
+ recon_buff[count].ion_alloc_fd.handle = recon_buff[count].alloc_data.handle;
+ rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_MAP,&recon_buff[count].ion_alloc_fd);
+ if(rc) {
+ DEBUG_PRINT_ERROR("\n ION MAP failed ");
+ recon_buff[count].ion_alloc_fd.fd =-1;
+ recon_buff[count].ion_alloc_fd.fd =-1;
+ return -1;
+ }
+ pmem_fd = recon_buff[count].ion_alloc_fd.fd;
+#else
+ struct pmem_allocation allocation;
+ pmem_fd = open(MEM_DEVICE, O_RDWR);
+
+ if ((int)(pmem_fd) < 0)
+ {
+ DEBUG_PRINT_ERROR("\n Failed to get an pmem handle");
+ return -1;
+ }
+
+ allocation.size = size;
+ allocation.align = clip2(alignment);
+
+ if (allocation.align != 8192)
+ allocation.align = 8192;
+
+ if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
+ {
+ DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
+ allocation.align, allocation.size);
+ return -1;
+ }
+#endif
+ buf_addr = mmap(NULL, size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, pmem_fd, 0);
+
+ if (buf_addr == (void*) MAP_FAILED)
+ {
+ close(pmem_fd);
+ pmem_fd = -1;
+ DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr);
+#ifdef USE_ION
+ if(ioctl(recon_buff[count].ion_device_fd,ION_IOC_FREE,
+ &recon_buff[count].alloc_data.handle)) {
+ DEBUG_PRINT_ERROR("ion recon buffer free failed");
+ }
+ recon_buff[count].alloc_data.handle = NULL;
+ recon_buff[count].ion_alloc_fd.fd =-1;
+ close(recon_buff[count].ion_device_fd);
+ recon_buff[count].ion_device_fd =-1;
+#endif
+ return -1;
+ }
+
+ DEBUG_PRINT_HIGH("\n Allocated virt:%p, FD: %d of size %d \n", buf_addr, pmem_fd, size);
+
+ recon_addr.buffer_size = size;
+ recon_addr.pmem_fd = pmem_fd;
+ recon_addr.offset = 0;
+ recon_addr.pbuffer = (unsigned char *)buf_addr;
+
+ ioctl_msg.in = (void*)&recon_addr;
+ ioctl_msg.out = NULL;
+
+ if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RECON_BUFFER, (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("Failed to set the Recon_buffers\n");
+ return -1;
+ }
+
+ recon_buff[count].virtual_address = (unsigned char *) buf_addr;
+ recon_buff[count].size = size;
+ recon_buff[count].offset = 0;
+ recon_buff[count].pmem_fd = pmem_fd;
+
+ DEBUG_PRINT_ERROR("\n Allocated virt:%p, FD: %d of size %d at index: %d\n", recon_buff[count].virtual_address,
+ recon_buff[count].pmem_fd, recon_buff[count].size, count);
+ return 0;
+}
+
+OMX_U32 venc_dev::pmem_free()
+{
+ int cnt = 0;
+ struct venc_ioctl_msg ioctl_msg;
+ struct venc_recon_addr recon_addr;
+ for (cnt = 0; cnt < recon_buffers_count; cnt++)
+ {
+ if(recon_buff[cnt].pmem_fd)
+ {
+ recon_addr.pbuffer = recon_buff[cnt].virtual_address;
+ recon_addr.offset = recon_buff[cnt].offset;
+ recon_addr.pmem_fd = recon_buff[cnt].pmem_fd;
+ recon_addr.buffer_size = recon_buff[cnt].size;
+ ioctl_msg.in = (void*)&recon_addr;
+ ioctl_msg.out = NULL;
+ if(ioctl(m_nDriver_fd, VEN_IOCTL_FREE_RECON_BUFFER ,&ioctl_msg) < 0)
+ DEBUG_PRINT_ERROR("VEN_IOCTL_FREE_RECON_BUFFER failed");
+ munmap(recon_buff[cnt].virtual_address, recon_buff[cnt].size);
+ close(recon_buff[cnt].pmem_fd);
+#ifdef USE_ION
+ if(ioctl(recon_buff[cnt].ion_device_fd,ION_IOC_FREE,
+ &recon_buff[cnt].alloc_data.handle)) {
+ DEBUG_PRINT_ERROR("ion recon buffer free failed");
+ }
+ recon_buff[cnt].alloc_data.handle = NULL;
+ recon_buff[cnt].ion_alloc_fd.fd =-1;
+ close(recon_buff[cnt].ion_device_fd);
+ recon_buff[cnt].ion_device_fd =-1;
+#endif
+ DEBUG_PRINT_LOW("\n cleaning Index %d of size %d \n",cnt,recon_buff[cnt].size);
+ recon_buff[cnt].pmem_fd = -1;
+ recon_buff[cnt].virtual_address = NULL;
+ recon_buff[cnt].offset = 0;
+ recon_buff[cnt].alignment = 0;
+ recon_buff[cnt].size = 0;
+ }
+ }
+ return 0;
+}
+#endif
+
+void venc_dev::venc_config_print()
+{
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %d, Profile %d, level : %d",
+ m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
+
+ DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %d, Height:%d, Fps: %d",
+ m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
+ m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d",
+ bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %d, qpP: %d, qpb: 0",
+ session_qp.iframeqp, session_qp.pframqp);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d",
+ voptimecfg.voptime_resolution, multislice.mslice_mode,
+ multislice.mslice_size);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %d",
+ entropy.longentropysel, entropy.cabacmodel);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d\n",
+ dbkfilter.db_mode, dbkfilter.slicealpha_offset,
+ dbkfilter.slicebeta_offset);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %d, HEC: %d\n",
+ intra_refresh.mbcount, hec.header_extension);
+}
+
+unsigned venc_dev::venc_flush( unsigned port)
+{
+ struct venc_ioctl_msg ioctl_msg;
+ struct venc_bufferflush buffer_index;
+
+ if(port == PORT_INDEX_IN)
+ {
+ DEBUG_PRINT_HIGH("Calling Input Flush");
+ buffer_index.flush_mode = VEN_FLUSH_INPUT;
+ ioctl_msg.in = (void*)&buffer_index;
+ ioctl_msg.out = NULL;
+
+ return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
+ }
+ else if(port == PORT_INDEX_OUT)
+ {
+ DEBUG_PRINT_HIGH("Calling Output Flush");
+ buffer_index.flush_mode = VEN_FLUSH_OUTPUT;
+ ioctl_msg.in = (void*)&buffer_index;
+ ioctl_msg.out = NULL;
+ return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+//allocating I/P memory from pmem and register with the device
+
+
+bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned)
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct pmem *pmem_tmp;
+ struct venc_bufferpayload dev_buffer = {0};
+
+ pmem_tmp = (struct pmem *)buf_addr;
+
+ DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
+
+ if(port == PORT_INDEX_IN)
+ {
+ dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
+ dev_buffer.fd = pmem_tmp->fd;
+ dev_buffer.maped_size = pmem_tmp->size;
+ dev_buffer.sz = pmem_tmp->size;
+ dev_buffer.offset = pmem_tmp->offset;
+ ioctl_msg.in = (void*)&dev_buffer;
+ ioctl_msg.out = NULL;
+
+ DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
+ dev_buffer.pbuffer, \
+ dev_buffer.fd, \
+ dev_buffer.offset, \
+ dev_buffer.maped_size);
+
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set input buffer failed ");
+ return false;
+ }
+ }
+ else if(port == PORT_INDEX_OUT)
+ {
+ dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
+ dev_buffer.fd = pmem_tmp->fd;
+ dev_buffer.sz = pmem_tmp->size;
+ dev_buffer.maped_size = pmem_tmp->size;
+ dev_buffer.offset = pmem_tmp->offset;
+ ioctl_msg.in = (void*)&dev_buffer;
+ ioctl_msg.out = NULL;
+
+ DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
+ dev_buffer.pbuffer, \
+ dev_buffer.fd, \
+ dev_buffer.offset, \
+ dev_buffer.maped_size);
+
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set output buffer failed ");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index ");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct pmem *pmem_tmp;
+ struct venc_bufferpayload dev_buffer = {0};
+
+ pmem_tmp = (struct pmem *)buf_addr;
+
+ DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
+
+ if(port == PORT_INDEX_IN)
+ {
+ dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
+ dev_buffer.fd = pmem_tmp->fd;
+ dev_buffer.maped_size = pmem_tmp->size;
+ dev_buffer.sz = pmem_tmp->size;
+ dev_buffer.offset = pmem_tmp->offset;
+ ioctl_msg.in = (void*)&dev_buffer;
+ ioctl_msg.out = NULL;
+
+ DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
+ dev_buffer.pbuffer, \
+ dev_buffer.fd, \
+ dev_buffer.offset, \
+ dev_buffer.maped_size);
+
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free input buffer failed ");
+ return false;
+ }
+ }
+ else if(port == PORT_INDEX_OUT)
+ {
+ dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
+ dev_buffer.fd = pmem_tmp->fd;
+ dev_buffer.sz = pmem_tmp->size;
+ dev_buffer.maped_size = pmem_tmp->size;
+ dev_buffer.offset = pmem_tmp->offset;
+ ioctl_msg.in = (void*)&dev_buffer;
+ ioctl_msg.out = NULL;
+
+ DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
+ dev_buffer.pbuffer, \
+ dev_buffer.fd, \
+ dev_buffer.offset, \
+ dev_buffer.maped_size);
+
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free output buffer failed ");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index ");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
+{
+ struct venc_buffer frameinfo;
+ struct pmem *temp_buffer;
+ struct venc_ioctl_msg ioctl_msg;
+ struct OMX_BUFFERHEADERTYPE *bufhdr;
+
+ if(buffer == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL");
+ return false;
+ }
+ bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
+
+ DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen);
+
+ if(pmem_data_buf)
+ {
+ DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
+ frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
+ frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
+ }
+
+ frameinfo.clientdata = (void *) buffer;
+ frameinfo.sz = bufhdr->nFilledLen;
+ frameinfo.len = bufhdr->nFilledLen;
+ frameinfo.flags = bufhdr->nFlags;
+ frameinfo.offset = bufhdr->nOffset;
+ frameinfo.timestamp = bufhdr->nTimeStamp;
+ DEBUG_PRINT_LOW("\n i/p TS = %u", (OMX_U32)frameinfo.timestamp);
+ ioctl_msg.in = &frameinfo;
+ ioctl_msg.out = NULL;
+
+ DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
+ bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
+ if(ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0)
+ {
+ /*Generate an async error and move to invalid state*/
+ return false;
+ }
+#ifdef INPUT_BUFFER_LOG
+#ifdef MAX_RES_1080P
+
+ int y_size = 0;
+ int c_offset = 0;
+ unsigned char *buf_addr = NULL;
+
+ y_size = m_sVenc_cfg.input_width * m_sVenc_cfg.input_height;
+ //chroma offset is y_size aligned to the 2k boundary
+ c_offset= (y_size + 2047) & (~(2047));
+
+ if(pmem_data_buf)
+ {
+ DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
+ buf_addr = (OMX_U8 *)pmem_data_buf;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
+ buf_addr = (unsigned char *)mmap(NULL,
+ ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2],
+ PROT_READ|PROT_WRITE, MAP_SHARED,
+ ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[0], 0);
+ }
+
+ if(inputBufferFile1)
+ {
+ fwrite((const char *)buf_addr, y_size, 1,inputBufferFile1);
+ fwrite((const char *)(buf_addr + c_offset), (y_size>>1), 1,inputBufferFile1);
+ }
+
+ munmap (buf_addr, ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2]);
+#else
+ if(inputBufferFile1)
+ {
+ fwrite((const char *)frameinfo.ptrbuffer, frameinfo.len, 1,inputBufferFile1);
+ }
+#endif
+
+#endif
+ return true;
+}
+bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct pmem *temp_buffer = NULL;
+ struct venc_buffer frameinfo;
+ struct OMX_BUFFERHEADERTYPE *bufhdr;
+
+ if(buffer == NULL)
+ {
+ return false;
+ }
+ bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
+
+ if(pmem_data_buf)
+ {
+ DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
+ frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
+ frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
+ }
+
+ frameinfo.clientdata = buffer;
+ frameinfo.sz = bufhdr->nAllocLen;
+ frameinfo.flags = bufhdr->nFlags;
+ frameinfo.offset = bufhdr->nOffset;
+
+ ioctl_msg.in = &frameinfo;
+ ioctl_msg.out = NULL;
+ DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
+ bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_slice_delivery_mode(OMX_BOOL enable)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ DEBUG_PRINT_HIGH("Set slice_delivery_mode: %d", enable);
+ if(multislice.mslice_mode == VEN_MSLICE_CNT_MB)
+ {
+ if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_SLICE_DELIVERY_MODE) < 0)
+ {
+ DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("WARNING: slice_mode[%d] is not VEN_MSLICE_CNT_MB to set "
+ "slice delivery mode to the driver.", multislice.mslice_mode);
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_extradata(OMX_U32 extra_data)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ DEBUG_PRINT_HIGH("venc_set_extradata:: %x", extra_data);
+ ioctl_msg.in = (void*)&extra_data;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_EXTRADATA, (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_sessionqp qp = {0, 0};
+ DEBUG_PRINT_LOW("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp,
+ p_frame_qp);
+
+ qp.iframeqp = i_frame_qp;
+ qp.pframqp = p_frame_qp;
+
+ ioctl_msg.in = (void*)&qp;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting session qp failed");
+ return false;
+ }
+
+ session_qp.iframeqp = i_frame_qp;
+ session_qp.pframqp = p_frame_qp;
+
+ return true;
+}
+
+bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_profile requested_profile;
+ struct ven_profilelevel requested_level;
+ unsigned const int *profile_tbl = NULL;
+ unsigned long mb_per_frame = 0, mb_per_sec = 0;
+ DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %d, Level = %d",
+ eProfile, eLevel);
+ mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
+ ((m_sVenc_cfg.input_width + 15) >> 4);
+ if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set)
+ {
+ DEBUG_PRINT_LOW("\n Profile/Level setting complete before venc_start");
+ return true;
+ }
+
+ if(eProfile && eLevel)
+ {
+ /* non-zero values will be set by user, saving the same*/
+ m_eProfile = eProfile;
+ m_eLevel = eLevel;
+ DEBUG_PRINT_HIGH("Profile/Level set equal to %d/%d",m_eProfile, m_eLevel);
+ }
+
+ DEBUG_PRINT_LOW("\n Validating Profile/Level from table");
+ if(!venc_validate_profile_level(&eProfile, &eLevel))
+ {
+ DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed");
+ return false;
+ }
+
+ if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
+ {
+ DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and "
+ "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile,
+ OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
+ if(eProfile == OMX_VIDEO_MPEG4ProfileSimple)
+ {
+ requested_profile.profile = VEN_PROFILE_MPEG4_SP;
+ profile_tbl = (unsigned int const *)
+ (&mpeg4_profile_level_table[MPEG4_SP_START]);
+ profile_tbl += MPEG4_720P_LEVEL*5;
+ }
+ else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
+ {
+ requested_profile.profile = VEN_PROFILE_MPEG4_ASP;
+ profile_tbl = (unsigned int const *)
+ (&mpeg4_profile_level_table[MPEG4_ASP_START]);
+ profile_tbl += MPEG4_720P_LEVEL*5;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u",
+ eProfile);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
+ "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
+ "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
+ OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
+
+ if(mb_per_frame >= 3600)
+ {
+ if(requested_profile.profile == VEN_PROFILE_MPEG4_ASP)
+ requested_level.level = VEN_LEVEL_MPEG4_5;
+ if(requested_profile.profile == VEN_PROFILE_MPEG4_SP)
+ requested_level.level = VEN_LEVEL_MPEG4_6;
+ }
+ else
+ {
+ switch(eLevel)
+ {
+ case OMX_VIDEO_MPEG4Level0:
+ requested_level.level = VEN_LEVEL_MPEG4_0;
+ break;
+ case OMX_VIDEO_MPEG4Level1:
+ requested_level.level = VEN_LEVEL_MPEG4_1;
+ break;
+ case OMX_VIDEO_MPEG4Level2:
+ requested_level.level = VEN_LEVEL_MPEG4_2;
+ break;
+ case OMX_VIDEO_MPEG4Level3:
+ requested_level.level = VEN_LEVEL_MPEG4_3;
+ break;
+ case OMX_VIDEO_MPEG4Level4a:
+ requested_level.level = VEN_LEVEL_MPEG4_4;
+ break;
+ case OMX_VIDEO_MPEG4Level5:
+ mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den);
+ if((requested_profile.profile == VEN_PROFILE_MPEG4_SP) && (mb_per_frame >= profile_tbl[0]) &&
+ (mb_per_sec >= profile_tbl[1]))
+ {
+ DEBUG_PRINT_LOW("\nMPEG4 Level 6 is set for 720p resolution");
+ requested_level.level = VEN_LEVEL_MPEG4_6;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\nMPEG4 Level 5 is set for non-720p resolution");
+ requested_level.level = VEN_LEVEL_MPEG4_5;
+ }
+ break;
+ default:
+ return false;
+ // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
+ break;
+ }
+ }
+ }
+ else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
+ {
+ if(eProfile == OMX_VIDEO_H263ProfileBaseline)
+ {
+ requested_profile.profile = VEN_PROFILE_H263_BASELINE;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u",
+ requested_profile.profile);
+ return false;
+ }
+ //profile level
+ switch(eLevel)
+ {
+ case OMX_VIDEO_H263Level10:
+ requested_level.level = VEN_LEVEL_H263_10;
+ break;
+ case OMX_VIDEO_H263Level20:
+ requested_level.level = VEN_LEVEL_H263_20;
+ break;
+ case OMX_VIDEO_H263Level30:
+ requested_level.level = VEN_LEVEL_H263_30;
+ break;
+ case OMX_VIDEO_H263Level40:
+ requested_level.level = VEN_LEVEL_H263_40;
+ break;
+ case OMX_VIDEO_H263Level45:
+ requested_level.level = VEN_LEVEL_H263_45;
+ break;
+ case OMX_VIDEO_H263Level50:
+ requested_level.level = VEN_LEVEL_H263_50;
+ break;
+ case OMX_VIDEO_H263Level60:
+ requested_level.level = VEN_LEVEL_H263_60;
+ break;
+ case OMX_VIDEO_H263Level70:
+ requested_level.level = VEN_LEVEL_H263_70;
+ break;
+ default:
+ return false;
+ break;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
+ {
+ if(eProfile == OMX_VIDEO_AVCProfileBaseline)
+ {
+ requested_profile.profile = VEN_PROFILE_H264_BASELINE;
+ }
+ else if(eProfile == OMX_VIDEO_AVCProfileMain)
+ {
+ requested_profile.profile = VEN_PROFILE_H264_MAIN;
+ }
+ else if(eProfile == OMX_VIDEO_AVCProfileHigh)
+ {
+ requested_profile.profile = VEN_PROFILE_H264_HIGH;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u",
+ requested_profile.profile);
+ return false;
+ }
+ //profile level
+ switch(eLevel)
+ {
+ case OMX_VIDEO_AVCLevel1:
+ requested_level.level = VEN_LEVEL_H264_1;
+ break;
+ case OMX_VIDEO_AVCLevel1b:
+ requested_level.level = VEN_LEVEL_H264_1b;
+ break;
+ case OMX_VIDEO_AVCLevel11:
+ requested_level.level = VEN_LEVEL_H264_1p1;
+ break;
+ case OMX_VIDEO_AVCLevel12:
+ requested_level.level = VEN_LEVEL_H264_1p2;
+ break;
+ case OMX_VIDEO_AVCLevel13:
+ requested_level.level = VEN_LEVEL_H264_1p3;
+ break;
+ case OMX_VIDEO_AVCLevel2:
+ requested_level.level = VEN_LEVEL_H264_2;
+ break;
+ case OMX_VIDEO_AVCLevel21:
+ requested_level.level = VEN_LEVEL_H264_2p1;
+ break;
+ case OMX_VIDEO_AVCLevel22:
+ requested_level.level = VEN_LEVEL_H264_2p2;
+ break;
+ case OMX_VIDEO_AVCLevel3:
+ requested_level.level = VEN_LEVEL_H264_3;
+ break;
+ case OMX_VIDEO_AVCLevel31:
+ requested_level.level = VEN_LEVEL_H264_3p1;
+ break;
+ case OMX_VIDEO_AVCLevel32:
+ requested_level.level = VEN_LEVEL_H264_3p2;
+ break;
+ case OMX_VIDEO_AVCLevel4:
+ requested_level.level = VEN_LEVEL_H264_4;
+ break;
+ default :
+ DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %u",
+ requested_level.level);
+ return false;
+ break;
+ }
+ }
+ if(!m_profile_set)
+ {
+ ioctl_msg.in = (void*)&requested_profile;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting profile failed");
+ return false;
+ }
+ codec_profile.profile = requested_profile.profile;
+ m_profile_set = true;
+ }
+
+ if(!m_level_set)
+ {
+ ioctl_msg.in = (void*)&requested_level;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting profile level failed");
+ return false;
+ }
+ profile_level.level = requested_level.level;
+ m_level_set = true;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_voptimingcfg vop_timing_cfg;
+
+ DEBUG_PRINT_LOW("\n venc_set_voptiming_cfg: TimeRes = %u",
+ TimeIncRes);
+
+ vop_timing_cfg.voptime_resolution = TimeIncRes;
+
+ ioctl_msg.in = (void*)&vop_timing_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_VOP_TIMING_CFG,(void*)&ioctl_msg)< 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Vop Timing failed");
+ return false;
+ }
+
+ voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
+ return true;
+}
+
+bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_intraperiod intraperiod_cfg;
+
+ DEBUG_PRINT_LOW("\n venc_set_intra_period: nPFrames = %u",
+ nPFrames);
+ intraperiod_cfg.num_pframes = nPFrames;
+ if((codec_profile.profile == VEN_PROFILE_MPEG4_ASP) ||
+ (codec_profile.profile == VEN_PROFILE_H264_MAIN) ||
+ (codec_profile.profile == VEN_PROFILE_H264_HIGH))
+ {
+#ifdef MAX_RES_1080P
+ if (nBFrames)
+ {
+ DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
+ intraperiod_cfg.num_bframes = 1;
+ }
+ else
+ intraperiod_cfg.num_bframes = 0;
+#else
+ if(nBFrames)
+ {
+ DEBUG_PRINT_ERROR("B frames not supported");
+ intraperiod_cfg.num_bframes = 0;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("B frames not supported");
+ intraperiod_cfg.num_bframes = 0;
+ }
+#endif
+ }
+ else
+ intraperiod_cfg.num_bframes = 0;
+
+ DEBUG_PRINT_ERROR("\n venc_set_intra_period: nPFrames = %u nBFrames = %u",
+ intraperiod_cfg.num_pframes, intraperiod_cfg.num_bframes);
+ ioctl_msg.in = (void*)&intraperiod_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+
+ intra_period.num_pframes = intraperiod_cfg.num_pframes;
+ intra_period.num_bframes = intraperiod_cfg.num_bframes;
+ return true;
+}
+
+bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_entropycfg entropy_cfg;
+
+ memset(&entropy_cfg,0,sizeof(entropy_cfg));
+ DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level);
+
+ if(enable &&(codec_profile.profile != VEN_PROFILE_H264_BASELINE)){
+ entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CABAC;
+ if (i_cabac_level == 0) {
+ entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
+ }
+#ifdef MAX_RES_1080P
+ else
+ {
+ DEBUG_PRINT_HIGH("Invalid model set (%d) defaulting to model 0",i_cabac_level);
+ entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
+ }
+#else
+ else if (i_cabac_level == 1) {
+ entropy_cfg.cabacmodel = VEN_CABAC_MODEL_1;
+ }
+ else if (i_cabac_level == 2) {
+ entropy_cfg.cabacmodel = VEN_CABAC_MODEL_2;
+ }
+#endif
+ }
+ else if(!enable){
+ entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CAVLC;
+ }
+ else{
+ DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile");
+ return false;
+ }
+
+ ioctl_msg.in = (void*)&entropy_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_ENTROPY_CFG,(void*)&ioctl_msg)< 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting entropy config failed");
+ return false;
+ }
+ entropy.longentropysel = entropy_cfg.longentropysel;
+ entropy.cabacmodel = entropy_cfg.cabacmodel;
+ return true;
+}
+
+bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
+{
+ venc_ioctl_msg ioctl_msg = {NULL, NULL};
+ bool status = true;
+ struct venc_multiclicecfg multislice_cfg;
+
+ if((Codec != OMX_IndexParamVideoH263) && (nSlicesize)){
+ multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB;
+ multislice_cfg.mslice_size = nSlicesize;
+ }
+ else{
+ multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
+ multislice_cfg.mslice_size = 0;
+ }
+
+ DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
+ multislice_cfg.mslice_size);
+
+ ioctl_msg.in = (void*)&multislice_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
+ status = false;
+ }
+ else
+ {
+ multislice.mslice_mode = multislice_cfg.mslice_mode;
+ multislice.mslice_size = nSlicesize;
+ }
+ return status;
+}
+
+bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
+{
+ venc_ioctl_msg ioctl_msg = {NULL, NULL};
+ bool status = true;
+ struct venc_intrarefresh intraRefresh_cfg;
+
+ // There is no disabled mode. Disabled mode is indicated by a 0 count.
+ if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax)
+ {
+ intraRefresh_cfg.irmode = VEN_IR_OFF;
+ intraRefresh_cfg.mbcount = 0;
+ }
+ else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
+ (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8)))
+ {
+ intraRefresh_cfg.irmode = VEN_IR_CYCLIC;
+ intraRefresh_cfg.mbcount = irMBs;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:"
+ "mb count: %d, mb mode:%d", irMBs, ir_mode);
+ return false;
+ }
+
+ ioctl_msg.in = (void*)&intraRefresh_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_REFRESH,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra Refresh failed");
+ status = false;
+ }
+ else
+ {
+ intra_refresh.irmode = intraRefresh_cfg.irmode;
+ intra_refresh.mbcount = intraRefresh_cfg.mbcount;
+ }
+ return status;
+}
+
+bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
+{
+ venc_ioctl_msg ioctl_msg = {NULL, NULL};
+ bool status = true;
+ struct venc_headerextension hec_cfg;
+ struct venc_multiclicecfg multislice_cfg;
+
+ if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingMPEG4) {
+ if (error_resilience->bEnableHEC) {
+ hec_cfg.header_extension = 1;
+ }
+ else {
+ hec_cfg.header_extension = 0;
+ }
+
+ ioctl_msg.in = (void*)&hec_cfg;
+ ioctl_msg.out = NULL;
+ if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_HEC,(void*)&ioctl_msg) < 0) {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting HEader Error correction failed");
+ return false;
+ }
+ hec.header_extension = error_resilience->bEnableHEC;
+ }
+
+ if (error_resilience->bEnableRVLC) {
+ DEBUG_PRINT_ERROR("\n RVLC is not Supported");
+ return false;
+ }
+
+ if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
+ (error_resilience->bEnableDataPartitioning)) {
+ DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264");
+ return false;
+ }
+
+ if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
+ (error_resilience->nResynchMarkerSpacing)) {
+ multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
+ multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing;
+ }
+ else if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingH263 &&
+ error_resilience->bEnableDataPartitioning) {
+ multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
+ multislice_cfg.mslice_size = 0;
+ }
+ else {
+ multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
+ multislice_cfg.mslice_size = 0;
+ }
+ DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
+ multislice_cfg.mslice_size);
+ ioctl_msg.in = (void*)&multislice_cfg;
+ ioctl_msg.out = NULL;
+ if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
+ status = false;
+ }
+ else
+ {
+ multislice.mslice_mode = multislice_cfg.mslice_mode ;
+ multislice.mslice_size = multislice_cfg.mslice_size;
+
+ }
+ return status;
+}
+
+bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_dbcfg filter_cfg;
+
+ memset(&filter_cfg, 0, sizeof(filter_cfg));
+ DEBUG_PRINT_LOW("\n venc_set_inloop_filter: %u",loopfilter);
+
+ if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable){
+ filter_cfg.db_mode = VEN_DB_ALL_BLKG_BNDRY;
+ }
+ else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisable){
+ filter_cfg.db_mode = VEN_DB_DISABLE;
+ }
+ else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary){
+ filter_cfg.db_mode = VEN_DB_SKIP_SLICE_BNDRY;
+ }
+ filter_cfg.slicealpha_offset = filter_cfg.slicebeta_offset = 0;
+
+ ioctl_msg.in = (void*)&filter_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_DEBLOCKING_CFG,(void*)&ioctl_msg)< 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting inloop filter failed");
+ return false;
+ }
+
+ dbkfilter.db_mode = filter_cfg.db_mode;
+ dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
+ return true;
+}
+
+bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
+{
+ venc_ioctl_msg ioctl_msg = {NULL, NULL};
+ struct venc_targetbitrate bitrate_cfg;
+
+ DEBUG_PRINT_LOW("\n venc_set_target_bitrate: bitrate = %u",
+ nTargetBitrate);
+ bitrate_cfg.target_bitrate = nTargetBitrate ;
+ ioctl_msg.in = (void*)&bitrate_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting bit rate failed");
+ return false;
+ }
+ m_sVenc_cfg.targetbitrate = nTargetBitrate;
+ bitrate.target_bitrate = nTargetBitrate;
+ if(!config)
+ {
+ m_level_set = false;
+ if(venc_set_profile_level(0, 0))
+ {
+ DEBUG_PRINT_LOW("Calling set level (Bitrate) with %d\n",profile_level.level);
+ }
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
+{
+ venc_ioctl_msg ioctl_msg = {NULL, NULL};
+ struct venc_framerate frame_rate_cfg;
+
+ Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
+
+ DEBUG_PRINT_LOW("\n venc_set_encode_framerate: framerate(Q16) = %u,NR: %d, DR: %d",
+ encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
+
+ ioctl_msg.in = (void*)&frame_rate_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting framerate failed");
+ return false;
+ }
+
+ m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
+ m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
+ if(!config)
+ {
+ m_level_set = false;
+ if(venc_set_profile_level(0, 0))
+ {
+ DEBUG_PRINT_LOW("Calling set level (Framerate) with %d\n",profile_level.level);
+ }
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
+{
+ venc_ioctl_msg ioctl_msg = {NULL, NULL};
+ DEBUG_PRINT_LOW("\n venc_set_color_format: color_format = %u ", color_format);
+
+ if(color_format == OMX_COLOR_FormatYUV420SemiPlanar)
+ {
+#ifdef MAX_RES_1080P
+ m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
+#else
+ m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
+#endif
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format);
+#ifdef MAX_RES_1080P
+ m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
+#else
+ m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
+#endif
+ DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set");
+ }
+ ioctl_msg.in = (void*)&m_sVenc_cfg;
+ ioctl_msg.out = NULL;
+ if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting color format failed");
+ return false;
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
+{
+ DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
+ if(intra_vop_refresh == OMX_TRUE)
+ {
+ if(ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra VOP Refresh failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect");
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ bool status = true;
+ struct venc_ratectrlcfg ratectrl_cfg;
+
+ //rate control
+ switch(eControlRate)
+ {
+ case OMX_Video_ControlRateDisable:
+ ratectrl_cfg.rcmode = VEN_RC_OFF;
+ break;
+ case OMX_Video_ControlRateVariableSkipFrames:
+ ratectrl_cfg.rcmode = VEN_RC_VBR_VFR;
+ break;
+ case OMX_Video_ControlRateVariable:
+ ratectrl_cfg.rcmode = VEN_RC_VBR_CFR;
+ break;
+ case OMX_Video_ControlRateConstantSkipFrames:
+ ratectrl_cfg.rcmode = VEN_RC_CBR_VFR;
+ break;
+ case OMX_Video_ControlRateConstant:
+ ratectrl_cfg.rcmode = VEN_RC_CBR_CFR;
+ break;
+ default:
+ status = false;
+ break;
+ }
+
+ if(status)
+ {
+ ioctl_msg.in = (void*)&ratectrl_cfg;
+ ioctl_msg.out = NULL;
+ if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting rate control failed");
+ status = false;
+ }
+ else
+ rate_ctrl.rcmode = ratectrl_cfg.rcmode;
+ }
+ return status;
+}
+
+bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
+{
+ bool status = true;
+ if(eProfile == NULL || eLevel == NULL)
+ {
+ return false;
+ }
+
+ if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
+ {
+ switch(codec_profile.profile)
+ {
+ case VEN_PROFILE_MPEG4_SP:
+ *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ break;
+ case VEN_PROFILE_MPEG4_ASP:
+ *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
+ break;
+ default:
+ *eProfile = OMX_VIDEO_MPEG4ProfileMax;
+ status = false;
+ break;
+ }
+
+ if(!status)
+ {
+ return status;
+ }
+
+ //profile level
+ switch(profile_level.level)
+ {
+ case VEN_LEVEL_MPEG4_0:
+ *eLevel = OMX_VIDEO_MPEG4Level0;
+ break;
+ case VEN_LEVEL_MPEG4_1:
+ *eLevel = OMX_VIDEO_MPEG4Level1;
+ break;
+ case VEN_LEVEL_MPEG4_2:
+ *eLevel = OMX_VIDEO_MPEG4Level2;
+ break;
+ case VEN_LEVEL_MPEG4_3:
+ *eLevel = OMX_VIDEO_MPEG4Level3;
+ break;
+ case VEN_LEVEL_MPEG4_4:
+ *eLevel = OMX_VIDEO_MPEG4Level4a;
+ break;
+ case VEN_LEVEL_MPEG4_5:
+ case VEN_LEVEL_MPEG4_6:
+ *eLevel = OMX_VIDEO_MPEG4Level5;
+ break;
+ default:
+ *eLevel = OMX_VIDEO_MPEG4LevelMax;
+ status = false;
+ break;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
+ {
+ if(codec_profile.profile == VEN_PROFILE_H263_BASELINE)
+ {
+ *eProfile = OMX_VIDEO_H263ProfileBaseline;
+ }
+ else
+ {
+ *eProfile = OMX_VIDEO_H263ProfileMax;
+ return false;
+ }
+ switch(profile_level.level)
+ {
+ case VEN_LEVEL_H263_10:
+ *eLevel = OMX_VIDEO_H263Level10;
+ break;
+ case VEN_LEVEL_H263_20:
+ *eLevel = OMX_VIDEO_H263Level20;
+ break;
+ case VEN_LEVEL_H263_30:
+ *eLevel = OMX_VIDEO_H263Level30;
+ break;
+ case VEN_LEVEL_H263_40:
+ *eLevel = OMX_VIDEO_H263Level40;
+ break;
+ case VEN_LEVEL_H263_45:
+ *eLevel = OMX_VIDEO_H263Level45;
+ break;
+ case VEN_LEVEL_H263_50:
+ *eLevel = OMX_VIDEO_H263Level50;
+ break;
+ case VEN_LEVEL_H263_60:
+ *eLevel = OMX_VIDEO_H263Level60;
+ break;
+ case VEN_LEVEL_H263_70:
+ *eLevel = OMX_VIDEO_H263Level70;
+ break;
+ default:
+ *eLevel = OMX_VIDEO_H263LevelMax;
+ status = false;
+ break;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
+ {
+ switch(codec_profile.profile)
+ {
+ case VEN_PROFILE_H264_BASELINE:
+ *eProfile = OMX_VIDEO_AVCProfileBaseline;
+ break;
+ case VEN_PROFILE_H264_MAIN:
+ *eProfile = OMX_VIDEO_AVCProfileMain;
+ break;
+ case VEN_PROFILE_H264_HIGH:
+ *eProfile = OMX_VIDEO_AVCProfileHigh;
+ break;
+ default:
+ *eProfile = OMX_VIDEO_AVCProfileMax;
+ status = false;
+ break;
+ }
+
+ if(!status)
+ {
+ return status;
+ }
+
+ switch(profile_level.level)
+ {
+ case VEN_LEVEL_H264_1:
+ *eLevel = OMX_VIDEO_AVCLevel1;
+ break;
+ case VEN_LEVEL_H264_1b:
+ *eLevel = OMX_VIDEO_AVCLevel1b;
+ break;
+ case VEN_LEVEL_H264_1p1:
+ *eLevel = OMX_VIDEO_AVCLevel11;
+ break;
+ case VEN_LEVEL_H264_1p2:
+ *eLevel = OMX_VIDEO_AVCLevel12;
+ break;
+ case VEN_LEVEL_H264_1p3:
+ *eLevel = OMX_VIDEO_AVCLevel13;
+ break;
+ case VEN_LEVEL_H264_2:
+ *eLevel = OMX_VIDEO_AVCLevel2;
+ break;
+ case VEN_LEVEL_H264_2p1:
+ *eLevel = OMX_VIDEO_AVCLevel21;
+ break;
+ case VEN_LEVEL_H264_2p2:
+ *eLevel = OMX_VIDEO_AVCLevel22;
+ break;
+ case VEN_LEVEL_H264_3:
+ *eLevel = OMX_VIDEO_AVCLevel3;
+ break;
+ case VEN_LEVEL_H264_3p1:
+ *eLevel = OMX_VIDEO_AVCLevel31;
+ break;
+ case VEN_LEVEL_H264_3p2:
+ *eLevel = OMX_VIDEO_AVCLevel32;
+ break;
+ case VEN_LEVEL_H264_4:
+ *eLevel = OMX_VIDEO_AVCLevel4;
+ break;
+ default :
+ *eLevel = OMX_VIDEO_AVCLevelMax;
+ status = false;
+ break;
+ }
+ }
+ return status;
+}
+
+bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
+{
+ OMX_U32 new_profile = 0, new_level = 0;
+ unsigned const int *profile_tbl = NULL;
+ OMX_U32 mb_per_frame, mb_per_sec;
+ bool profile_level_found = false;
+
+ DEBUG_PRINT_LOW("\n Init profile table for respective codec");
+ //validate the ht,width,fps,bitrate and set the appropriate profile and level
+ if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
+ {
+ if(*eProfile == 0)
+ {
+ if(!m_profile_set)
+ {
+ *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ }
+ else
+ {
+ switch(codec_profile.profile)
+ {
+ case VEN_PROFILE_MPEG4_ASP:
+ *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
+ break;
+ case VEN_PROFILE_MPEG4_SP:
+ *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ break;
+ default:
+ DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
+ return false;
+ }
+ }
+ }
+
+ if(*eLevel == 0 && !m_level_set)
+ {
+ *eLevel = OMX_VIDEO_MPEG4LevelMax;
+ }
+
+ if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple)
+ {
+ profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
+ }
+ else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
+ {
+ profile_tbl = (unsigned int const *)
+ (&mpeg4_profile_level_table[MPEG4_ASP_START]);
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile);
+ return false;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
+ {
+ if(*eProfile == 0)
+ {
+ if(!m_profile_set)
+ {
+ *eProfile = OMX_VIDEO_AVCProfileBaseline;
+ }
+ else
+ {
+ switch(codec_profile.profile)
+ {
+ case VEN_PROFILE_H264_BASELINE:
+ *eProfile = OMX_VIDEO_AVCProfileBaseline;
+ break;
+ case VEN_PROFILE_H264_MAIN:
+ *eProfile = OMX_VIDEO_AVCProfileMain;
+ break;
+ case VEN_PROFILE_H264_HIGH:
+ *eProfile = OMX_VIDEO_AVCProfileHigh;
+ break;
+ default:
+ DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
+ return false;
+ }
+ }
+ }
+
+ if(*eLevel == 0 && !m_level_set)
+ {
+ *eLevel = OMX_VIDEO_AVCLevelMax;
+ }
+
+ if(*eProfile == OMX_VIDEO_AVCProfileBaseline)
+ {
+ profile_tbl = (unsigned int const *)h264_profile_level_table;
+ }
+ else if(*eProfile == OMX_VIDEO_AVCProfileHigh)
+ {
+ profile_tbl = (unsigned int const *)
+ (&h264_profile_level_table[H264_HP_START]);
+ }
+ else if(*eProfile == OMX_VIDEO_AVCProfileMain)
+ {
+ profile_tbl = (unsigned int const *)
+ (&h264_profile_level_table[H264_MP_START]);
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile);
+ return false;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
+ {
+ if(*eProfile == 0)
+ {
+ if(!m_profile_set)
+ {
+ *eProfile = OMX_VIDEO_H263ProfileBaseline;
+ }
+ else
+ {
+ switch(codec_profile.profile)
+ {
+ case VEN_PROFILE_H263_BASELINE:
+ *eProfile = OMX_VIDEO_H263ProfileBaseline;
+ break;
+ default:
+ DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
+ return false;
+ }
+ }
+ }
+
+ if(*eLevel == 0 && !m_level_set)
+ {
+ *eLevel = OMX_VIDEO_H263LevelMax;
+ }
+
+ if(*eProfile == OMX_VIDEO_H263ProfileBaseline)
+ {
+ profile_tbl = (unsigned int const *)h263_profile_level_table;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile);
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Invalid codec type");
+ return false;
+ }
+
+ mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
+ ((m_sVenc_cfg.input_width + 15)>> 4);
+
+ if((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4))
+ {
+ if(codec_profile.profile == VEN_PROFILE_MPEG4_ASP)
+ profile_level.level = VEN_LEVEL_MPEG4_5;
+ if(codec_profile.profile == VEN_PROFILE_MPEG4_SP)
+ profile_level.level = VEN_LEVEL_MPEG4_6;
+ {
+ new_level = profile_level.level;
+ new_profile = codec_profile.profile;
+ return true;
+ }
+ }
+
+ mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
+
+ do{
+ if(mb_per_frame <= (int)profile_tbl[0])
+ {
+ if(mb_per_sec <= (int)profile_tbl[1])
+ {
+ if(m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2])
+ {
+ new_level = (int)profile_tbl[3];
+ new_profile = (int)profile_tbl[4];
+ profile_level_found = true;
+ DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level);
+ break;
+ }
+ }
+ }
+ profile_tbl = profile_tbl + 5;
+ }while(profile_tbl[0] != 0);
+
+ if (profile_level_found != true)
+ {
+ DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n");
+ return false;
+ }
+
+ if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
+ || (*eLevel == OMX_VIDEO_H263LevelMax))
+ {
+ *eLevel = new_level;
+ }
+ DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu"
+ "Level = %lu", __func__, *eProfile, *eLevel);
+
+ return true;
+}
+
+bool venc_dev::venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate)
+{
+ unsigned const int *profile_tbl = NULL;
+
+ switch(m_sVenc_cfg.codectype)
+ {
+ case VEN_CODEC_MPEG4:
+ if(m_eProfile == OMX_VIDEO_MPEG4ProfileSimple)
+ {
+ profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
+ }
+ else if(m_eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
+ {
+ profile_tbl = (unsigned int const *)
+ (&mpeg4_profile_level_table[MPEG4_ASP_START]);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Unsupported MPEG4 profile type %lu", m_eProfile);
+ return false;
+ }
+ break;
+ case VEN_CODEC_H264:
+ if(m_eProfile == OMX_VIDEO_AVCProfileBaseline)
+ {
+ profile_tbl = (unsigned int const *)h264_profile_level_table;
+ }
+ else if(m_eProfile == OMX_VIDEO_AVCProfileHigh)
+ {
+ profile_tbl = (unsigned int const *)
+ (&h264_profile_level_table[H264_HP_START]);
+ }
+ else if(m_eProfile == OMX_VIDEO_AVCProfileMain)
+ {
+ profile_tbl = (unsigned int const *)
+ (&h264_profile_level_table[H264_MP_START]);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Unsupported AVC profile type %lu", m_eProfile);
+ return false;
+ }
+
+ break;
+ case VEN_CODEC_H263:
+ if(m_eProfile == OMX_VIDEO_H263ProfileBaseline)
+ {
+ profile_tbl = (unsigned int const *)h263_profile_level_table;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Unsupported H.263 profile type %lu", m_eProfile);
+ return false;
+ }
+ break;
+ default:
+ DEBUG_PRINT_ERROR("%s: unknown codec type", __func__);
+ return false;
+ }
+ while(profile_tbl[0] != 0)
+ {
+ if(profile_tbl[3] == m_eLevel)
+ {
+ if(nTargetBitrate > profile_tbl[2])
+ {
+ DEBUG_PRINT_ERROR("Max. supported bitrate for Profile[%d] & Level[%d]"
+ " is %u", m_eProfile, m_eLevel, profile_tbl[2]);
+ return false;
+ }
+ }
+ profile_tbl += 5;
+ }
+ return true;
+}
+
+#ifdef _ANDROID_ICS_
+bool venc_dev::venc_set_meta_mode(bool mode)
+{
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ ioctl_msg.in = &mode;
+ DEBUG_PRINT_HIGH("Set meta buffer mode: %d", mode);
+ if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_METABUFFER_MODE,&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR(" Set meta buffer mode failed");
+ return false;
+ }
+ return true;
+}
+#endif
diff --git a/mm-video/vidc/venc/src/video_encoder_device_copper.cpp b/mm-video/vidc/venc/src/video_encoder_device_copper.cpp
new file mode 100755
index 0000000..1b387ed
--- /dev/null
+++ b/mm-video/vidc/venc/src/video_encoder_device_copper.cpp
@@ -0,0 +1,3012 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#include<string.h>
+#include <sys/ioctl.h>
+#include <sys/prctl.h>
+#include<unistd.h>
+#include <fcntl.h>
+#include "video_encoder_device_copper.h"
+#include "omx_video_encoder.h"
+#include <linux/android_pmem.h>
+#ifdef USE_ION
+#include <ion_msm.h>
+#endif
+
+#define MPEG4_SP_START 0
+#define MPEG4_ASP_START (MPEG4_SP_START + 8)
+#define MPEG4_720P_LEVEL 6
+#define H263_BP_START 0
+#define H264_BP_START 0
+#define H264_HP_START (H264_BP_START + 13)
+#define H264_MP_START (H264_BP_START + 26)
+
+/* MPEG4 profile and level table*/
+static const unsigned int mpeg4_profile_level_table[][5]=
+{
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
+ {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
+ {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
+ {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
+ {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
+ {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
+ {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
+ {0,0,0,0,0},
+
+ {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {0,0,0,0,0},
+};
+
+/* H264 profile and level table*/
+static const unsigned int h264_profile_level_table[][5]=
+{
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
+ {0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
+ {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
+ {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
+ {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
+ {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
+ {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
+ {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
+ {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
+ {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
+ {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
+ {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
+ {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
+ {0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
+ {0,0,0,0,0}
+
+};
+
+/* H263 profile and level table*/
+static const unsigned int h263_profile_level_table[][5]=
+{
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
+ {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
+ {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
+ {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
+ {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
+ {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
+ {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
+ {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
+ {0,0,0,0,0}
+};
+
+#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
+#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
+
+#ifdef INPUT_BUFFER_LOG
+FILE *inputBufferFile1;
+char inputfilename [] = "/data/input.yuv";
+#endif
+#ifdef OUTPUT_BUFFER_LOG
+FILE *outputBufferFile1;
+char outputfilename [] = "/data/output-bitstream.\0\0\0\0";
+#endif
+//constructor
+venc_dev::venc_dev(class omx_venc *venc_class)
+{
+//nothing to do
+venc_handle = venc_class;
+etb_count=0;
+}
+
+venc_dev::~venc_dev()
+{
+ //nothing to do
+}
+
+void* async_venc_message_thread (void *input)
+{
+ struct venc_timeout timeout;
+ struct venc_msg venc_msg;
+ omx_video* omx_venc_base = NULL;
+ omx_venc *omx = reinterpret_cast<omx_venc*>(input);
+ omx_venc_base = reinterpret_cast<omx_video*>(input);
+ OMX_BUFFERHEADERTYPE* omxhdr = NULL;
+
+
+ prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
+ timeout.millisec = VEN_TIMEOUT_INFINITE;
+ struct v4l2_plane plane;
+ struct pollfd pfd;
+ struct v4l2_buffer v4l2_buf ={0};
+ struct v4l2_event dqevent;
+ pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
+ pfd.fd = omx->handle->m_nDriver_fd;
+ int error_code = 0,rc=0;
+ while(1)
+ {
+ rc = poll(&pfd, 1, TIMEOUT);
+ if (!rc) {
+ printf("Poll timedout\n");
+ break;
+ } else if (rc < 0) {
+ printf("Error while polling: %d\n", rc);
+ break;
+ }
+ if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
+ v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ v4l2_buf.memory = V4L2_MEMORY_USERPTR;
+ v4l2_buf.length = 1;
+ v4l2_buf.m.planes = &plane;
+ rc = ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf);
+ if (rc) {
+ printf("Failed to dequeue buf: %d from capture capability\n", rc);
+ break;
+ }
+ venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
+ venc_msg.statuscode=VEN_S_SUCCESS;
+ omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
+ venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
+ venc_msg.buf.offset = v4l2_buf.m.planes->reserved[1];
+ venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
+
+ venc_msg.buf.clientdata=(void*)omxhdr;
+ } else if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
+ v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ v4l2_buf.memory = V4L2_MEMORY_USERPTR;
+ v4l2_buf.m.planes = &plane;
+ rc = ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf);
+ if (rc) {
+ printf("Failed to dequeue buf: %d from output capability\n", rc);
+ break;
+ }
+ venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
+ venc_msg.statuscode=VEN_S_SUCCESS;
+ omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index;
+ venc_msg.buf.clientdata=(void*)omxhdr;
+ } else if (pfd.revents & POLLPRI){
+ rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
+ printf("\n Data Recieved = %d \n",dqevent.u.data[0]);
+ if(dqevent.u.data[0] == MSM_VIDC_CLOSE_DONE){
+ break;
+ }
+ } else {
+ /*TODO: How to handle this case */
+ continue;
+ }
+
+ if(omx->async_message_process(input,&venc_msg) < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
+ break;
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n");
+ return NULL;
+}
+
+bool venc_dev::venc_open(OMX_U32 codec)
+{
+ int r;
+ unsigned int alignment = 0,buffer_size = 0, temp =0;
+
+ m_nDriver_fd = open ("/dev/video33",O_RDWR);
+ if(m_nDriver_fd == 0)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n");
+ m_nDriver_fd = open ("/dev/video33",O_RDWR);
+ }
+
+ if((int)m_nDriver_fd < 0)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd);
+#ifdef SINGLE_ENCODER_INSTANCE
+ OMX_U32 num_instances = 0;
+ if(/*ioctl (m_nDriver_fd, VEN_IOCTL_GET_NUMBER_INSTANCES, (void*)&ioctl_msg) < */0 )
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request number of encoder instances failed");
+ }
+ else if (num_instances > 1)
+ {
+ DEBUG_PRINT_ERROR("\nSecond encoder instance rejected!");
+ venc_close();
+ return false;
+ }
+#endif
+ // set the basic configuration of the video encoder driver
+ m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
+ m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
+ m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
+ m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
+ m_sVenc_cfg.fps_num = 30;
+ m_sVenc_cfg.fps_den = 1;
+ m_sVenc_cfg.targetbitrate = 64000;
+ m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12;
+ if(codec == OMX_VIDEO_CodingMPEG4)
+ {
+ m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
+ codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
+ profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
+#ifdef OUTPUT_BUFFER_LOG
+ strcat(outputfilename, "m4v");
+#endif
+ }
+ else if(codec == OMX_VIDEO_CodingH263)
+ {
+ m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
+ codec_profile.profile = VEN_PROFILE_H263_BASELINE;
+ profile_level.level = VEN_LEVEL_H263_20;
+#ifdef OUTPUT_BUFFER_LOG
+ strcat(outputfilename, "263");
+#endif
+ }
+ if(codec == OMX_VIDEO_CodingAVC)
+ {
+ m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
+ codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
+ profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
+#ifdef OUTPUT_BUFFER_LOG
+ strcat(outputfilename, "264");
+#endif
+ }
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < */0 )
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting base configuration failed");
+ return false;
+ }
+#ifdef INPUT_BUFFER_LOG
+ inputBufferFile1 = fopen (inputfilename, "ab");
+#endif
+#ifdef OUTPUT_BUFFER_LOG
+ outputBufferFile1 = fopen (outputfilename, "ab");
+#endif
+ int ret;
+ struct v4l2_event_subscription sub;
+ sub.type=V4L2_EVENT_ALL;
+ ret = ioctl(m_nDriver_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
+ if (ret) {
+ printf("\n Subscribe Event Failed \n");
+ return false;
+ }
+ struct v4l2_capability cap;
+ struct v4l2_fmtdesc fdesc;
+ struct v4l2_format fmt;
+ struct v4l2_requestbuffers bufreq;
+
+ ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
+ if (ret) {
+ printf("Failed to query capabilities\n");
+ } else {
+ printf("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
+ " version = %d, capabilities = %x\n", cap.driver, cap.card,
+ cap.bus_info, cap.version, cap.capabilities);
+ }
+ //printf(" \n VIDIOC_QUERYCAP Successful \n ");
+ ret=0;
+ fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fdesc.index=0;
+ while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
+ printf("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
+ fdesc.pixelformat, fdesc.flags);
+ fdesc.index++;
+ }
+ //printf("\n VIDIOC_ENUM_FMT CAPTURE Successful \n ");
+ fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fdesc.index=0;
+ while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
+
+ printf("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
+ fdesc.pixelformat, fdesc.flags);
+ fdesc.index++;
+ }
+ //printf(" \n VIDIOC_ENUM_FMT OUTPUT Successful \n ");
+
+ m_sOutput_buff_property.alignment=m_sInput_buff_property.alignment=4096;
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
+
+ ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
+ //printf(" \n VIDIOC_S_FMT OUTPUT Successful \n ");
+ m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+ //printf("m_sInput_buff_property.datasize = %d\n",m_sInput_buff_property.datasize);
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+
+ ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
+ //printf(" \n VIDIOC_S_FMT CAPTURE Successful \n ");
+ m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+ //printf("m_sOutput_buff_property.datasize = %d\n",m_sOutput_buff_property.datasize);
+// struct v4l2_requestbuffers bufreq;
+
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = 2;
+
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
+ m_sInput_buff_property.mincount=m_sInput_buff_property.maxcount=m_sInput_buff_property.actualcount=bufreq.count;
+ //printf(" \n VIDIOC_REQBUFS OUTPUT Successful \n ");
+ //printf("m_sInput_buff_property.datasize = %d\n",m_sInput_buff_property.datasize);
+ //printf("m_sInput_buff_property.mincount = %d\n",m_sInput_buff_property.mincount);
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ bufreq.count = 2;
+ ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
+ m_sOutput_buff_property.mincount=m_sOutput_buff_property.maxcount=m_sOutput_buff_property.actualcount=bufreq.count;
+ //printf(" \n VIDIOC_REQBUFS CAPTURE Successful \n ");
+ //printf("m_sInput_buff_property.mincount = %d\n",m_sOutput_buff_property.mincount);
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
+ return false;
+ }
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
+ return false;
+ }
+ ///printf("\n \n Setting Profile and Level \n \n ");
+ //m_profile_set = false;
+ //m_level_set = false;
+ if(/*venc_set_profile_level(0, 0)*/0)
+ {
+ DEBUG_PRINT_HIGH("\n %s(): Init Profile/Level setting success",
+ __func__);
+ }
+ recon_buffers_count = MAX_RECON_BUFFERS;
+ return true;
+}
+
+void venc_dev::venc_close()
+{
+ DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd);
+ if((int)m_nDriver_fd >= 0)
+ {
+ DEBUG_PRINT_HIGH("\n venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG");
+ //(void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG,
+ // NULL);
+ DEBUG_PRINT_LOW("\nCalling close()\n");
+
+ int rc=0;
+ enum v4l2_buf_type btype;
+ btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &btype);
+ if (rc) {
+ /* STREAMOFF will never fail */
+ printf("\n Failed to call streamoff on OUTPUT Port \n");
+ }
+ btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &btype);
+ if (rc) {
+ /* STREAMOFF will never fail */
+ printf("\n Failed to call streamoff on CAPTURE Port \n");
+ }
+ struct v4l2_event_subscription sub;
+ sub.type=V4L2_EVENT_ALL;
+ rc = ioctl(m_nDriver_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
+ if (rc) {
+ printf("Failed to get control\n");
+ return ;
+ }
+ close(m_nDriver_fd);
+ m_nDriver_fd = -1;
+ }
+#ifdef INPUT_BUFFER_LOG
+ fclose (inputBufferFile1);
+#endif
+#ifdef OUTPUT_BUFFER_LOG
+ fclose (outputBufferFile1);
+#endif
+}
+
+bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count,
+ unsigned long *actual_buff_count,
+ unsigned long *buff_size,
+ unsigned long port)
+{
+
+ unsigned long temp_count = 0;
+
+ if(port == 0)
+ {
+ if(*actual_buff_count > m_sInput_buff_property.mincount)
+ {
+ temp_count = m_sInput_buff_property.actualcount;
+ m_sInput_buff_property.actualcount = *actual_buff_count;
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirement failed");
+ m_sInput_buff_property.actualcount = temp_count;
+ return false;
+ }
+ DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count);
+ }
+ }
+ else
+ {
+ if(*actual_buff_count > m_sOutput_buff_property.mincount)
+ {
+ temp_count = m_sOutput_buff_property.actualcount;
+ m_sOutput_buff_property.actualcount = *actual_buff_count;
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer requirement failed");
+ m_sOutput_buff_property.actualcount = temp_count;
+ return false;
+ }
+ DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count);
+ }
+ }
+
+ return true;
+
+}
+
+bool venc_dev::venc_loaded_start()
+{
+ return true;
+}
+
+bool venc_dev::venc_loaded_stop()
+{
+ return true;
+}
+
+bool venc_dev::venc_loaded_start_done()
+{
+ return true;
+}
+
+bool venc_dev::venc_loaded_stop_done()
+{
+ return true;
+}
+
+bool venc_dev::venc_get_seq_hdr(void *buffer,
+ unsigned buffer_size, unsigned *header_len)
+{
+ return true;
+}
+
+bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count,
+ unsigned long *actual_buff_count,
+ unsigned long *buff_size,
+ unsigned long port)
+{
+ struct v4l2_format fmt;
+ struct v4l2_requestbuffers bufreq;
+ int ret;
+ if(port == 0)
+ {
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
+ return false;
+ }
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
+ ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
+ //printf(" \n VIDIOC_S_FMT OUTPUT Successful \n ");
+ m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+
+bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = 2;
+
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
+ m_sInput_buff_property.mincount=m_sInput_buff_property.maxcount=m_sInput_buff_property.actualcount=bufreq.count;
+
+
+ *min_buff_count = m_sInput_buff_property.mincount;
+ *actual_buff_count = m_sInput_buff_property.actualcount;
+#ifdef USE_ION
+ // For ION memory allocations of the allocated buffer size
+ // must be 4k aligned, hence aligning the input buffer
+ // size to 4k.
+ m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095)
+ & (~4095);
+#endif
+ *buff_size = m_sInput_buff_property.datasize;
+ }
+ else
+ {
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
+ return false;
+ }
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+
+ ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
+ //printf(" \n VIDIOC_S_FMT CAPTURE Successful \n ");
+ m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+
+ ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
+ //printf(" \n VIDIOC_S_FMT CAPTURE Successful \n ");
+ m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+
+
+ *min_buff_count = m_sOutput_buff_property.mincount;
+ *actual_buff_count = m_sOutput_buff_property.actualcount;
+ *buff_size = m_sOutput_buff_property.datasize;
+ }
+
+ return true;
+
+}
+
+bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
+{
+ DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n");
+ switch(index)
+ {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition\n");
+ if(portDefn->nPortIndex == PORT_INDEX_IN)
+ {
+ if(!venc_set_color_format(portDefn->format.video.eColorFormat))
+ {
+ return false;
+ }
+ if(m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
+ m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth)
+ {
+ DEBUG_PRINT_LOW("\n Basic parameter has changed");
+ m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
+ m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting base config failed");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("\n Updating the buffer count/size for the new resolution");
+ if(/*ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p bufreq failed");
+ return false;
+ }
+ DEBUG_PRINT_LOW("\n Got updated m_sInput_buff_property values: "
+ "datasize = %u, maxcount = %u, actualcnt = %u, "
+ "mincount = %u", m_sInput_buff_property.datasize,
+ m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount,
+ m_sInput_buff_property.mincount);
+
+ if(/*ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p bufreq failed");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("\n Got updated m_sOutput_buff_property values: "
+ "datasize = %u, maxcount = %u, actualcnt = %u, "
+ "mincount = %u", m_sOutput_buff_property.datasize,
+ m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount,
+ m_sOutput_buff_property.mincount);
+ if(/*ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) <*/ 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p bufreq failed");
+ return false;
+ }
+
+ if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
+ (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount))
+ {
+ m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
+ if(/*ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirements failed");
+ return false;
+ }
+ }
+ if(m_sInput_buff_property.datasize != portDefn->nBufferSize)
+ {
+ DEBUG_PRINT_ERROR("\nWARNING: Requested i/p bufsize[%u],"
+ "Driver's updated i/p bufsize = %u", portDefn->nBufferSize,
+ m_sInput_buff_property.datasize);
+ }
+ m_level_set = false;
+ if(venc_set_profile_level(0, 0))
+ {
+ DEBUG_PRINT_HIGH("\n %s(): Profile/Level setting success", __func__);
+ }
+ }
+ else
+ {
+ if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
+ (m_sInput_buff_property.maxcount >= portDefn->nBufferCountActual) &&
+ (m_sInput_buff_property.datasize == portDefn->nBufferSize))
+ {
+ m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_INPUT_BUFFER_REQ failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Input buffer requirements failed");
+ return false;
+ }
+ }
+ }
+ else if(portDefn->nPortIndex == PORT_INDEX_OUT)
+ {
+ if(!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0))
+ {
+ return false;
+ }
+
+ if(!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0))
+ {
+ return false;
+ }
+
+ if( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
+ &&
+ (m_sOutput_buff_property.maxcount >= portDefn->nBufferCountActual)
+ &&
+ (m_sOutput_buff_property.datasize == portDefn->nBufferSize)
+ )
+ {
+ m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
+ portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n");
+
+ if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
+ {
+ if(!venc_set_color_format(portFmt->eColorFormat))
+ {
+ return false;
+ }
+ }
+ else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(!venc_set_encode_framerate(portFmt->xFramerate, 0))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoBitrate:
+ {
+ OMX_VIDEO_PARAM_BITRATETYPE* pParam;
+ pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n");
+
+ if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(!venc_set_target_bitrate(pParam->nTargetBitrate, 0))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed");
+ return false;
+ }
+ if(!venc_set_ratectrl_cfg(pParam->eControlRate))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4:
+ {
+ OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
+ OMX_U32 bFrames = 0;
+
+ pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n");
+ if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(!venc_set_voptiming_cfg(pParam->nTimeIncRes))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed");
+ return false;
+ }
+ m_profile_set = false;
+ m_level_set = false;
+ if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
+ return false;
+ }
+ else {
+ if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
+ {
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
+ bFrames = 1;
+ }
+ }
+ else
+ {
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
+ bFrames = 0;
+ }
+ }
+ }
+ if(!venc_set_intra_period (pParam->nPFrames,bFrames))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+ if(!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoH263:
+ {
+ OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n");
+ OMX_U32 bFrames = 0;
+ if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ m_profile_set = false;
+ m_level_set = false;
+ if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
+ return false;
+ }
+ if (pParam->nBFrames)
+ DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263");
+
+ if(venc_set_intra_period (pParam->nPFrames, bFrames) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoAvc:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n");
+ OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
+ OMX_U32 bFrames = 0;
+
+ if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n",
+ pParam->eProfile,pParam->eLevel);
+
+ m_profile_set = false;
+ m_level_set = false;
+
+ if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d",
+ pParam->eProfile, pParam->eLevel);
+ return false;
+ }
+ else {
+ if(pParam->eProfile != OMX_VIDEO_AVCProfileBaseline)
+ {
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
+ bFrames = 1;
+ }
+ }
+ else
+ {
+ if(pParam->nBFrames)
+ {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
+ bFrames = 0;
+ }
+ }
+ }
+ if(!venc_set_intra_period (pParam->nPFrames, bFrames))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+ if(!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed");
+ return false;
+ }
+ if(!venc_set_inloop_filter (pParam->eLoopFilterMode))
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed");
+ printf("\n \n Returned here line line 903 \n \n ");
+ return false;
+ }
+ if(!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing))
+ {
+ DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
+ }
+ //TBD, lot of other variables to be updated, yet to decide
+ break;
+ }
+ case OMX_IndexParamVideoIntraRefresh:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n");
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
+ (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
+ if(intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(/*venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == */false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoErrorCorrection:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n");
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
+ (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
+ if(error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(venc_set_error_resilience(error_resilience) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n");
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
+ (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
+ if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ m_profile_set = false;
+ m_level_set = false;
+ if(!venc_set_profile_level (profile_level->eProfile,
+ profile_level->eLevel))
+ {
+ DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoQuantization:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n");
+ OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
+ (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
+ if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(venc_set_session_qp (session_qp->nQpI,
+ session_qp->nQpP,
+ session_qp->nQpB) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
+ }
+ break;
+ }
+ case OMX_IndexParamVideoSliceFMO:
+ default:
+ DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u",
+ index);
+ break;
+ //case
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
+{
+
+ DEBUG_PRINT_LOW("\n Inside venc_set_config");
+
+ switch(index)
+ {
+ case OMX_IndexConfigVideoBitrate:
+ {
+ OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
+ configData;
+ DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate");
+ if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
+ {
+ if(venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
+ configData;
+ DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate");
+ if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
+ {
+ if(venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
+ }
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n");
+ QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
+ (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
+ if(intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
+ {
+ if(venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ {
+ OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
+ configData;
+ DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
+ if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
+ {
+ if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
+ }
+ break;
+ }
+ case OMX_IndexConfigCommonRotate:
+ {
+ OMX_CONFIG_ROTATIONTYPE *config_rotation =
+ reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
+ OMX_U32 nFrameWidth;
+
+ DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims");
+ nFrameWidth = m_sVenc_cfg.input_width;
+ m_sVenc_cfg.input_width = m_sVenc_cfg.input_height;
+ m_sVenc_cfg.input_height = nFrameWidth;
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < */0) {
+ DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed");
+ return false;
+ }
+ break;
+ }
+ default:
+ DEBUG_PRINT_ERROR("\n Unsupported config index = %u", index);
+ break;
+ }
+
+ return true;
+}
+
+unsigned venc_dev::venc_stop( void)
+{
+ pmem_free();
+ return 0;
+}
+
+unsigned venc_dev::venc_pause(void)
+{
+ return 0;
+}
+
+unsigned venc_dev::venc_resume(void)
+{
+ return 0;
+}
+
+unsigned venc_dev::venc_start_done(void)
+{
+ struct venc_msg venc_msg;
+ venc_msg.msgcode=VEN_MSG_START;
+ venc_msg.statuscode=VEN_S_SUCCESS;
+ venc_handle->async_message_process(venc_handle,&venc_msg);
+ return 0;
+}
+
+unsigned venc_dev::venc_stop_done(void)
+{
+ struct venc_msg venc_msg;
+ venc_msg.msgcode=VEN_MSG_STOP;
+ venc_msg.statuscode=VEN_S_SUCCESS;
+ venc_handle->async_message_process(venc_handle,&venc_msg);
+ return 0;
+}
+
+unsigned venc_dev::venc_start(void)
+{
+ enum v4l2_buf_type buf_type;
+ int ret,r;
+ DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start",
+ __func__);
+ if (!venc_set_profile_level(0, 0))
+ {
+ DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET",
+ __func__);
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET",
+ __func__, codec_profile.profile, profile_level.level);
+ }
+ venc_config_print();
+
+
+ if((codec_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) ||
+ (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) ||
+ (codec_profile.profile == VEN_PROFILE_H263_BASELINE))
+ recon_buffers_count = MAX_RECON_BUFFERS - 2;
+ else
+ recon_buffers_count = MAX_RECON_BUFFERS;
+
+ buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
+
+ ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
+
+ if (ret) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
+}
+
+OMX_U32 venc_dev::pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count)
+{
+ OMX_U32 pmem_fd = -1;
+ OMX_U32 width, height;
+ void *buf_addr = NULL;
+ struct pmem_allocation allocation;
+ struct venc_recon_addr recon_addr;
+ int rc = 0;
+
+#ifdef USE_ION
+ recon_buff[count].ion_device_fd = open (MEM_DEVICE,O_RDONLY|O_DSYNC);
+ if(recon_buff[count].ion_device_fd < 0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
+ return -1;
+ }
+
+ recon_buff[count].alloc_data.len = size;
+ recon_buff[count].alloc_data.flags = 0x1 << MEM_HEAP_ID;
+ recon_buff[count].alloc_data.align = clip2(alignment);
+ if (recon_buff[count].alloc_data.align != 8192)
+ recon_buff[count].alloc_data.align = 8192;
+
+ rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_ALLOC,&recon_buff[count].alloc_data);
+ if(rc || !recon_buff[count].alloc_data.handle) {
+ DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
+ recon_buff[count].alloc_data.handle=NULL;
+ return -1;
+ }
+
+ recon_buff[count].ion_alloc_fd.handle = recon_buff[count].alloc_data.handle;
+ rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_MAP,&recon_buff[count].ion_alloc_fd);
+ if(rc) {
+ DEBUG_PRINT_ERROR("\n ION MAP failed ");
+ recon_buff[count].ion_alloc_fd.fd =-1;
+ recon_buff[count].ion_alloc_fd.fd =-1;
+ return -1;
+ }
+ pmem_fd = recon_buff[count].ion_alloc_fd.fd;
+#else
+ pmem_fd = open(MEM_DEVICE, O_RDWR);
+
+ if ((int)(pmem_fd) < 0)
+ {
+ DEBUG_PRINT_ERROR("\n Failed to get an pmem handle");
+ return -1;
+ }
+
+ allocation.size = size;
+ allocation.align = clip2(alignment);
+
+ if (allocation.align != 8192)
+ allocation.align = 8192;
+
+ if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
+ {
+ DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
+ allocation.align, allocation.size);
+ return -1;
+ }
+#endif
+ buf_addr = mmap(NULL, size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, pmem_fd, 0);
+
+ if (buf_addr == (void*) MAP_FAILED)
+ {
+ close(pmem_fd);
+ pmem_fd = -1;
+ DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr);
+#ifdef USE_ION
+ if(ioctl(recon_buff[count].ion_device_fd,ION_IOC_FREE,
+ &recon_buff[count].alloc_data.handle)) {
+ DEBUG_PRINT_ERROR("ion recon buffer free failed");
+ }
+ recon_buff[count].alloc_data.handle = NULL;
+ recon_buff[count].ion_alloc_fd.fd =-1;
+ close(recon_buff[count].ion_device_fd);
+ recon_buff[count].ion_device_fd =-1;
+#endif
+ return -1;
+ }
+
+ DEBUG_PRINT_HIGH("\n Allocated virt:%p, FD: %d of size %d \n", buf_addr, pmem_fd, size);
+
+ recon_addr.buffer_size = size;
+ recon_addr.pmem_fd = pmem_fd;
+ recon_addr.offset = 0;
+ recon_addr.pbuffer = (unsigned char *)buf_addr;
+
+
+ if (/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_RECON_BUFFER, (void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("Failed to set the Recon_buffers\n");
+ return -1;
+ }
+
+ recon_buff[count].virtual_address = (unsigned char *) buf_addr;
+ recon_buff[count].size = size;
+ recon_buff[count].offset = 0;
+ recon_buff[count].pmem_fd = pmem_fd;
+
+ DEBUG_PRINT_ERROR("\n Allocated virt:%p, FD: %d of size %d at index: %d\n", recon_buff[count].virtual_address,
+ recon_buff[count].pmem_fd, recon_buff[count].size, count);
+ return 0;
+}
+
+OMX_U32 venc_dev::pmem_free()
+{
+ int cnt = 0;
+ struct venc_recon_addr recon_addr;
+ for (cnt = 0; cnt < recon_buffers_count; cnt++)
+ {
+ if(recon_buff[cnt].pmem_fd)
+ {
+ recon_addr.pbuffer = recon_buff[cnt].virtual_address;
+ recon_addr.offset = recon_buff[cnt].offset;
+ recon_addr.pmem_fd = recon_buff[cnt].pmem_fd;
+ recon_addr.buffer_size = recon_buff[cnt].size;
+ if(/*ioctl(m_nDriver_fd, VEN_IOCTL_FREE_RECON_BUFFER ,&ioctl_msg) < */0)
+ DEBUG_PRINT_ERROR("VEN_IOCTL_FREE_RECON_BUFFER failed");
+ munmap(recon_buff[cnt].virtual_address, recon_buff[cnt].size);
+ close(recon_buff[cnt].pmem_fd);
+#ifdef USE_ION
+ if(ioctl(recon_buff[cnt].ion_device_fd,ION_IOC_FREE,
+ &recon_buff[cnt].alloc_data.handle)) {
+ DEBUG_PRINT_ERROR("ion recon buffer free failed");
+ }
+ recon_buff[cnt].alloc_data.handle = NULL;
+ recon_buff[cnt].ion_alloc_fd.fd =-1;
+ close(recon_buff[cnt].ion_device_fd);
+ recon_buff[cnt].ion_device_fd =-1;
+#endif
+ DEBUG_PRINT_LOW("\n cleaning Index %d of size %d \n",cnt,recon_buff[cnt].size);
+ recon_buff[cnt].pmem_fd = -1;
+ recon_buff[cnt].virtual_address = NULL;
+ recon_buff[cnt].offset = 0;
+ recon_buff[cnt].alignment = 0;
+ recon_buff[cnt].size = 0;
+ }
+ }
+ return 0;
+}
+void venc_dev::venc_config_print()
+{
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %d, Profile %d, level : %d",
+ m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
+
+ DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %d, Height:%d, Fps: %d",
+ m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
+ m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d",
+ bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %d, qpP: %d, qpb: %d",
+ session_qp.iframeqp, session_qp.pframqp,session_qp.bframqp);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d",
+ voptimecfg.voptime_resolution, multislice.mslice_mode,
+ multislice.mslice_size);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %d",
+ entropy.longentropysel, entropy.cabacmodel);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d\n",
+ dbkfilter.db_mode, dbkfilter.slicealpha_offset,
+ dbkfilter.slicebeta_offset);
+
+ DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %d, HEC: %d\n",
+ intra_refresh.mbcount, hec.header_extension);
+}
+
+unsigned venc_dev::venc_flush( unsigned port)
+{
+ struct venc_bufferflush buffer_index;
+
+ if(port == PORT_INDEX_IN)
+ {
+ int rc=0;
+ enum v4l2_buf_type btype;
+ btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &btype);
+ if (rc) {
+ /* STREAMOFF should never fail */
+ printf("\n Failed to call streamoff on OUTPUT Port \n");
+ return -1;
+ }
+
+ return 0;
+ }
+ else if(port == PORT_INDEX_OUT)
+ {
+ int rc=0;
+ enum v4l2_buf_type btype;
+ btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &btype);
+ if (rc) {
+ /* STREAMOFF should never fail */
+ printf("\n Failed to call streamoff on OUTPUT Port \n");
+ return -1;
+ }
+
+ return 0;
+
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+//allocating I/P memory from pmem and register with the device
+
+
+bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
+{
+
+ struct pmem *pmem_tmp;
+
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane;
+ int rc=0;
+
+ pmem_tmp = (struct pmem *)buf_addr;
+
+ DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
+
+ if(port == PORT_INDEX_IN)
+ {
+
+ buf.index = index;
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ plane.length = pmem_tmp->size;
+ plane.m.userptr = (unsigned long)pmem_tmp->buffer;
+ plane.reserved[0] = pmem_tmp->fd;
+ plane.reserved[1] = 0;
+ plane.data_offset = pmem_tmp->offset;
+ buf.m.planes = &plane;
+ buf.length = 1;
+
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
+
+ if (rc) {
+ printf("VIDIOC_PREPARE_BUF Failed at line 1387 \n");
+ }
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set input buffer failed ");
+ return false;
+ }
+ }
+ else if(port == PORT_INDEX_OUT)
+ {
+
+ buf.index = index;
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ plane.length = pmem_tmp->size;
+ plane.m.userptr = (unsigned long)pmem_tmp->buffer;
+ plane.reserved[0] = pmem_tmp->fd;
+ plane.reserved[1] = 0;
+ plane.data_offset = pmem_tmp->offset;
+ buf.m.planes = &plane;
+ buf.length = 1;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
+
+ if (rc) {
+ printf("VIDIOC_PREPARE_BUF Failed at line 1414 \n");
+ }
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set output buffer failed ");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index ");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
+{
+ struct pmem *pmem_tmp;
+ struct venc_bufferpayload dev_buffer = {0};
+
+ pmem_tmp = (struct pmem *)buf_addr;
+
+ DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
+
+ if(port == PORT_INDEX_IN)
+ {
+ dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
+ dev_buffer.fd = pmem_tmp->fd;
+ dev_buffer.maped_size = pmem_tmp->size;
+ dev_buffer.sz = pmem_tmp->size;
+ dev_buffer.offset = pmem_tmp->offset;
+ DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
+ dev_buffer.pbuffer, \
+ dev_buffer.fd, \
+ dev_buffer.offset, \
+ dev_buffer.maped_size);
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free input buffer failed ");
+ return false;
+ }
+ }
+ else if(port == PORT_INDEX_OUT)
+ {
+ dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
+ dev_buffer.fd = pmem_tmp->fd;
+ dev_buffer.sz = pmem_tmp->size;
+ dev_buffer.maped_size = pmem_tmp->size;
+ dev_buffer.offset = pmem_tmp->offset;
+
+ DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
+ dev_buffer.pbuffer, \
+ dev_buffer.fd, \
+ dev_buffer.offset, \
+ dev_buffer.maped_size);
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free output buffer failed ");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index ");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
+{
+ struct pmem *temp_buffer;
+
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane;
+ int rc=0;
+ struct OMX_BUFFERHEADERTYPE *bufhdr;
+
+ temp_buffer = (struct pmem *)buffer;
+
+
+ if(buffer == NULL)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL");
+ return false;
+ }
+ bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
+
+DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen);
+
+ if(pmem_data_buf)
+ {
+ DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
+ plane.m.userptr = (unsigned long)pmem_data_buf;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
+ plane.m.userptr = (unsigned long)bufhdr->pBuffer;
+ }
+
+ buf.index = index;
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ plane.length = bufhdr->nAllocLen;
+ plane.bytesused = bufhdr->nFilledLen;
+ plane.reserved[0] = fd;
+ plane.reserved[1] = 0;
+ plane.data_offset = bufhdr->nOffset;
+ buf.m.planes = &plane;
+ buf.length = 1;
+
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
+ if (rc) {
+ printf("Failed to qbuf to driver");
+ return false;
+ }
+
+ etb_count++;
+
+ if(etb_count == 1)
+ {
+ enum v4l2_buf_type buf_type;
+ buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ int ret;
+ ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
+ if (ret) {
+ printf("Failed to call streamon\n");
+ }
+
+ }
+
+ if(/*ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < */0)
+ {
+ /*Generate an async error and move to invalid state*/
+ return false;
+ }
+#ifdef INPUT_BUFFER_LOG
+
+ int y_size = 0;
+ int c_offset = 0;
+
+ y_size = m_sVenc_cfg.input_width * m_sVenc_cfg.input_height;
+ //chroma offset is y_size aligned to the 2k boundary
+ c_offset= (y_size + 2047) & (~(2047));
+
+ if(inputBufferFile1)
+ {
+ fwrite((const char *)frameinfo.ptrbuffer, y_size, 1,inputBufferFile1);
+ fwrite((const char *)(frameinfo.ptrbuffer + c_offset), (y_size>>1), 1,inputBufferFile1);
+ }
+#endif
+
+ return true;
+}
+bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
+{
+
+ struct pmem *temp_buffer = NULL;
+ struct venc_buffer frameinfo;
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane;
+ int rc=0;
+ struct OMX_BUFFERHEADERTYPE *bufhdr;
+
+ if(buffer == NULL)
+ {
+ return false;
+ }
+ bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
+
+if(pmem_data_buf)
+ {
+ DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
+ plane.m.userptr = (unsigned long)pmem_data_buf;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
+ plane.m.userptr = (unsigned long)bufhdr->pBuffer;
+ }
+
+ buf.index = index;
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ plane.length = bufhdr->nAllocLen;
+ plane.bytesused = bufhdr->nFilledLen;
+ plane.reserved[0] = fd;
+ plane.reserved[1] = 0;
+ plane.data_offset = bufhdr->nOffset;
+ buf.m.planes = &plane;
+ buf.length = 1;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
+ if (rc) {
+ printf("Failed to qbuf to driver");
+ return false;
+ }
+
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
+{
+ int rc;
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
+ control.value = i_frame_qp;
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+ session_qp.iframeqp = control.value;
+
+ control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
+ control.value = p_frame_qp;
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+ session_qp.pframqp = control.value;
+
+ if((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
+ (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH))
+ {
+
+ control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
+ control.value = b_frame_qp;
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+ session_qp.bframqp = control.value;
+ }
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting session qp failed");
+ return false;
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
+{
+ struct venc_profile requested_profile;
+ struct ven_profilelevel requested_level;
+ unsigned const int *profile_tbl = NULL;
+ unsigned long mb_per_frame = 0, mb_per_sec = 0;
+ DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %d, Level = %d",
+ eProfile, eLevel);
+ mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
+ ((m_sVenc_cfg.input_width + 15) >> 4);
+ if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set)
+ {
+ DEBUG_PRINT_LOW("\n Profile/Level setting complete before venc_start");
+ return true;
+ }
+
+ DEBUG_PRINT_LOW("\n Validating Profile/Level from table");
+ if(!venc_validate_profile_level(&eProfile, &eLevel))
+ {
+ DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed");
+ return false;
+ }
+
+ if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4)
+ {
+ DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and "
+ "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile,
+ OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
+ if(eProfile == OMX_VIDEO_MPEG4ProfileSimple)
+ {
+ requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
+ profile_tbl = (unsigned int const *)
+ (&mpeg4_profile_level_table[MPEG4_SP_START]);
+ profile_tbl += MPEG4_720P_LEVEL*5;
+ }
+ else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
+ {
+ requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
+ profile_tbl = (unsigned int const *)
+ (&mpeg4_profile_level_table[MPEG4_ASP_START]);
+ profile_tbl += MPEG4_720P_LEVEL*5;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u",
+ eProfile);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
+ "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
+ "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
+ OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
+
+ if(mb_per_frame >= 3600)
+ {
+ if(requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
+ if(requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
+ }
+ else
+ {
+ switch(eLevel)
+ {
+ case OMX_VIDEO_MPEG4Level0:
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
+ break;
+ case OMX_VIDEO_MPEG4Level0b:
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
+ break;
+ case OMX_VIDEO_MPEG4Level1:
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
+ break;
+ case OMX_VIDEO_MPEG4Level2:
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
+ break;
+ case OMX_VIDEO_MPEG4Level3:
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
+ break;
+ case OMX_VIDEO_MPEG4Level4a:
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
+ break;
+ case OMX_VIDEO_MPEG4Level5:
+ mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den);
+ if((requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) && (mb_per_frame >= profile_tbl[0]) &&
+ (mb_per_sec >= profile_tbl[1]))
+ {
+ DEBUG_PRINT_LOW("\nMPEG4 Level 6 is set for 720p resolution");
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\nMPEG4 Level 5 is set for non-720p resolution");
+ requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
+ }
+ break;
+ default:
+ return false;
+ // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
+ break;
+ }
+ }
+ }
+ else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263)
+ {
+ if(eProfile == OMX_VIDEO_H263ProfileBaseline)
+ {
+ requested_profile.profile = VEN_PROFILE_H263_BASELINE;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u",
+ requested_profile.profile);
+ return false;
+ }
+ //profile level
+ switch(eLevel)
+ {
+ case OMX_VIDEO_H263Level10:
+ requested_level.level = VEN_LEVEL_H263_10;
+ break;
+ case OMX_VIDEO_H263Level20:
+ requested_level.level = VEN_LEVEL_H263_20;
+ break;
+ case OMX_VIDEO_H263Level30:
+ requested_level.level = VEN_LEVEL_H263_30;
+ break;
+ case OMX_VIDEO_H263Level40:
+ requested_level.level = VEN_LEVEL_H263_40;
+ break;
+ case OMX_VIDEO_H263Level45:
+ requested_level.level = VEN_LEVEL_H263_45;
+ break;
+ case OMX_VIDEO_H263Level50:
+ requested_level.level = VEN_LEVEL_H263_50;
+ break;
+ case OMX_VIDEO_H263Level60:
+ requested_level.level = VEN_LEVEL_H263_60;
+ break;
+ case OMX_VIDEO_H263Level70:
+ requested_level.level = VEN_LEVEL_H263_70;
+ break;
+ default:
+ return false;
+ break;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264)
+ {
+ if(eProfile == OMX_VIDEO_AVCProfileBaseline)
+ {
+ requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
+ }
+ else if(eProfile == OMX_VIDEO_AVCProfileMain)
+ {
+ requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
+ }
+ else if(eProfile == OMX_VIDEO_AVCProfileExtended)
+ {
+ requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
+ }
+ else if(eProfile == OMX_VIDEO_AVCProfileHigh)
+ {
+ requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
+ }
+ else if(eProfile == OMX_VIDEO_AVCProfileHigh10)
+ {
+ requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
+ }
+ else if(eProfile == OMX_VIDEO_AVCProfileHigh422)
+ {
+ requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
+ }
+ else if(eProfile == OMX_VIDEO_AVCProfileHigh444)
+ {
+ requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u",
+ requested_profile.profile);
+ return false;
+ }
+ //profile level
+ switch(eLevel)
+ {
+ case OMX_VIDEO_AVCLevel1:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
+ break;
+ case OMX_VIDEO_AVCLevel1b:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
+ break;
+ case OMX_VIDEO_AVCLevel11:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
+ break;
+ case OMX_VIDEO_AVCLevel12:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
+ break;
+ case OMX_VIDEO_AVCLevel13:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
+ break;
+ case OMX_VIDEO_AVCLevel2:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
+ break;
+ case OMX_VIDEO_AVCLevel21:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
+ break;
+ case OMX_VIDEO_AVCLevel22:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
+ break;
+ case OMX_VIDEO_AVCLevel3:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
+ break;
+ case OMX_VIDEO_AVCLevel31:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
+ break;
+ case OMX_VIDEO_AVCLevel32:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
+ break;
+ case OMX_VIDEO_AVCLevel4:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
+ break;
+ case OMX_VIDEO_AVCLevel41:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
+ break;
+ case OMX_VIDEO_AVCLevel42:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
+ break;
+ case OMX_VIDEO_AVCLevel5:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
+ break;
+ case OMX_VIDEO_AVCLevel51:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
+ break;
+ default :
+ DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %u",
+ requested_level.level);
+ return false;
+ break;
+ }
+ }
+ if(!m_profile_set)
+ {
+ int rc;
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
+ control.value = requested_profile.profile;
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting profile failed");
+ return false;
+ }
+ codec_profile.profile = control.value;
+ m_profile_set = true;
+ }
+
+ if(!m_level_set)
+ {
+ int rc;
+ struct v4l2_control control;
+ control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
+ control.value = requested_level.level;
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting profile level failed");
+ return false;
+ }
+ profile_level.level = control.value;
+ m_level_set = true;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
+{
+
+ struct venc_voptimingcfg vop_timing_cfg;
+
+ DEBUG_PRINT_LOW("\n venc_set_voptiming_cfg: TimeRes = %u",
+ TimeIncRes);
+
+ vop_timing_cfg.voptime_resolution = TimeIncRes;
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_VOP_TIMING_CFG,(void*)&ioctl_msg)< */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Vop Timing failed");
+ return false;
+ }
+
+ voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
+ return true;
+}
+
+bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
+{
+
+ DEBUG_PRINT_LOW("\n venc_set_intra_period: nPFrames = %u",
+ nPFrames);
+ int rc;
+ struct v4l2_control control;
+ if((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
+ (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
+ (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH))
+ {
+ nBFrames=0;
+ }
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
+ control.value = nPFrames;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+ intra_period.num_pframes = control.value;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
+ control.value = nBFrames;
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
+ return false;
+ }
+ intra_period.num_bframes = control.value;
+ return true;
+}
+
+bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
+{
+ //struct venc_entropycfg entropy_cfg;
+
+ // memset(&entropy_cfg,0,sizeof(entropy_cfg));
+ int rc;
+ struct v4l2_control control;
+
+ DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level);
+
+ if(enable &&(codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE)){
+
+ control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
+ control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+ entropy.longentropysel = control.value;
+ if (i_cabac_level == 0) {
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
+ }
+ else if (i_cabac_level == 1) {
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
+ }
+ else if (i_cabac_level == 2) {
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
+ }
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
+ //control.value = entropy_cfg.cabacmodel;
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+ entropy.longentropysel=control.value;
+ }
+ else if(!enable){
+ control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
+ control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+ entropy.longentropysel=control.value;
+ //entropy_cfg.longentropysel = control.value;
+ }
+ else{
+ DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile");
+ return false;
+ }
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_ENTROPY_CFG,(void*)&ioctl_msg)< */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting entropy config failed");
+ return false;
+ }
+ //entropy.longentropysel = entropy_cfg.longentropysel;
+ //entropy.cabacmodel = entropy_cfg.cabacmodel;
+ return true;
+}
+
+bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
+{
+ int rc;
+ struct v4l2_control control;
+ bool status = true;
+ //struct venc_multiclicecfg multislice_cfg;
+
+ if((Codec != OMX_IndexParamVideoH263) && (nSlicesize)){
+ // multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB;
+ //multislice_cfg.mslice_size = nSlicesize;
+ control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
+ }
+ else{
+ control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
+ //multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
+ //multislice_cfg.mslice_size = 0;
+ }
+ control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+ multislice.mslice_mode=control.value;
+
+ if(multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE){
+
+ control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
+ control.value = nSlicesize;
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+ multislice.mslice_size=control.value;
+
+ }
+
+
+ if(/*ioctl (m_nDriver_fd, VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
+ status = false;
+ }
+ else
+ {
+ //multislice.mslice_mode = multislice_cfg.mslice_mode;
+ //multislice.mslice_size = nSlicesize;
+ }
+ return status;
+}
+
+bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
+{
+ bool status = true;
+ int rc;
+ struct v4l2_control control_mode,control_mbs;
+ control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
+ // There is no disabled mode. Disabled mode is indicated by a 0 count.
+ if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax)
+ {
+ control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
+ }
+ else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
+ (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8)))
+ {
+ control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
+ control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
+ control_mbs.value=irMBs;
+ }
+ else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
+ (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8)))
+ {
+ control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
+ control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
+ control_mbs.value=irMBs;
+ }
+ else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
+ (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8)))
+ {
+ control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:"
+ "mb count: %d, mb mode:%d", irMBs, ir_mode);
+ return false;
+ }
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control_mode.id, control_mode.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control_mode.id, control_mode.value);
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control_mbs.id, control_mbs.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control_mbs.id, control_mbs.value);
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_REFRESH,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra Refresh failed");
+ status = false;
+ }
+ else
+ {
+ intra_refresh.irmode = control_mode.value;
+ intra_refresh.mbcount = control_mbs.value;
+ }
+ return status;
+}
+
+bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
+{
+ bool status = true;
+ struct venc_headerextension hec_cfg;
+ struct venc_multiclicecfg multislice_cfg;
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
+ if (error_resilience->bEnableHEC) {
+ hec_cfg.header_extension = 1;
+ }
+ else {
+ hec_cfg.header_extension = 0;
+ }
+
+ if (/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_HEC,(void*)&ioctl_msg) < */0) {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting HEader Error correction failed");
+ return false;
+ }
+ hec.header_extension = error_resilience->bEnableHEC;
+ }
+
+ if (error_resilience->bEnableRVLC) {
+ DEBUG_PRINT_ERROR("\n RVLC is not Supported");
+ return false;
+ }
+
+ if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
+ (error_resilience->bEnableDataPartitioning)) {
+ DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264");
+ return false;
+ }
+
+ if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
+ (error_resilience->nResynchMarkerSpacing)) {
+ multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
+ multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing;
+ }
+ else if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingH263 &&
+ error_resilience->bEnableDataPartitioning) {
+ multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
+ multislice_cfg.mslice_size = 0;
+ }
+ else {
+ multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
+ multislice_cfg.mslice_size = 0;
+ }
+ DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
+ multislice_cfg.mslice_size);
+ if (/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < */0) {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
+ status = false;
+ }
+ else
+ {
+ multislice.mslice_mode = multislice_cfg.mslice_mode ;
+ multislice.mslice_size = multislice_cfg.mslice_size;
+
+ }
+ return status;
+}
+
+bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
+{
+ int rc;
+ struct v4l2_control control;
+ control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
+ if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable){
+ control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
+ }
+ else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisable){
+ control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
+ }
+ else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary){
+ control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
+ }
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+ dbkfilter.db_mode=control.value;
+
+ control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
+ control.value=0;
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+ control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
+ control.value=0;
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_DEBLOCKING_CFG,(void*)&ioctl_msg)< */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting inloop filter failed");
+ return false;
+ }
+
+ dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
+ return true;
+}
+
+bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
+{
+ DEBUG_PRINT_LOW("\n venc_set_target_bitrate: bitrate = %u",
+ nTargetBitrate);
+ struct v4l2_control control;
+ int rc;
+ control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
+ control.value = nTargetBitrate/1000;
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting bit rate failed");
+ return false;
+ }
+ m_sVenc_cfg.targetbitrate = control.value*1000;
+ bitrate.target_bitrate = control.value*1000;
+ if(!config)
+ {
+ m_level_set = false;
+ if(venc_set_profile_level(0, 0))
+ {
+ DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %d\n",profile_level.level);
+ }
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
+{
+
+ struct v4l2_control control;
+ int rc;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE;
+ control.value = encode_framerate;
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+ if(//ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE,
+ /*(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting framerate failed");
+ return false;
+ }
+
+ m_sVenc_cfg.fps_den = 1;
+ m_sVenc_cfg.fps_num = control.value;
+ if(!config)
+ {
+ m_level_set = false;
+ if(venc_set_profile_level(0, 0))
+ {
+ DEBUG_PRINT_HIGH("Calling set level (Framerate) with %d\n",profile_level.level);
+ }
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
+{
+ DEBUG_PRINT_LOW("\n venc_set_color_format: color_format = %u ", color_format);
+
+ if(color_format == OMX_COLOR_FormatYUV420SemiPlanar)
+ {
+ m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format);
+ m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
+ DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set");
+ }
+ if (/*ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting color format failed");
+ return false;
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
+{
+ DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
+ if(intra_vop_refresh == OMX_TRUE)
+ {
+ if(/*ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra VOP Refresh failed");
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect");
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
+{
+ bool status = true;
+ struct v4l2_control control;
+ int rc;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
+ switch(eControlRate)
+ {
+ case OMX_Video_ControlRateDisable:
+ control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
+ break;
+ case OMX_Video_ControlRateVariableSkipFrames:
+ control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
+ break;
+ case OMX_Video_ControlRateVariable:
+ control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
+ break;
+ case OMX_Video_ControlRateConstantSkipFrames:
+ control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR;
+ break;
+ case OMX_Video_ControlRateConstant:
+ control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
+ break;
+ default:
+ status = false;
+ break;
+ }
+
+ if(status)
+ {
+
+ printf("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ printf("Failed to set control\n");
+ return false;
+ }
+ printf("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value);
+
+
+ if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR("\nERROR: Request for setting rate control failed");
+ status = false;
+ }
+ else
+ rate_ctrl.rcmode = control.value;
+ }
+ return status;
+}
+
+bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
+{
+ bool status = true;
+ if(eProfile == NULL || eLevel == NULL)
+ {
+ return false;
+ }
+
+ if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4)
+ {
+ switch(codec_profile.profile)
+ {
+ case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
+ *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ break;
+ case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
+ *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
+ break;
+ default:
+ *eProfile = OMX_VIDEO_MPEG4ProfileMax;
+ status = false;
+ break;
+ }
+
+ if(!status)
+ {
+ return status;
+ }
+
+ //profile level
+ switch(profile_level.level)
+ {
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
+ *eLevel = OMX_VIDEO_MPEG4Level0;
+ break;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
+ *eLevel = OMX_VIDEO_MPEG4Level0b;
+ break;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
+ *eLevel = OMX_VIDEO_MPEG4Level1;
+ break;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
+ *eLevel = OMX_VIDEO_MPEG4Level2;
+ break;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
+ *eLevel = OMX_VIDEO_MPEG4Level3;
+ break;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
+ *eLevel = OMX_VIDEO_MPEG4Level4;
+ break;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
+ *eLevel = OMX_VIDEO_MPEG4Level5;
+ break;
+ default:
+ *eLevel = OMX_VIDEO_MPEG4LevelMax;
+ status = false;
+ break;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263)
+ {
+ if(codec_profile.profile == VEN_PROFILE_H263_BASELINE)
+ {
+ *eProfile = OMX_VIDEO_H263ProfileBaseline;
+ }
+ else
+ {
+ *eProfile = OMX_VIDEO_H263ProfileMax;
+ return false;
+ }
+ switch(profile_level.level)
+ {
+ case VEN_LEVEL_H263_10:
+ *eLevel = OMX_VIDEO_H263Level10;
+ break;
+ case VEN_LEVEL_H263_20:
+ *eLevel = OMX_VIDEO_H263Level20;
+ break;
+ case VEN_LEVEL_H263_30:
+ *eLevel = OMX_VIDEO_H263Level30;
+ break;
+ case VEN_LEVEL_H263_40:
+ *eLevel = OMX_VIDEO_H263Level40;
+ break;
+ case VEN_LEVEL_H263_45:
+ *eLevel = OMX_VIDEO_H263Level45;
+ break;
+ case VEN_LEVEL_H263_50:
+ *eLevel = OMX_VIDEO_H263Level50;
+ break;
+ case VEN_LEVEL_H263_60:
+ *eLevel = OMX_VIDEO_H263Level60;
+ break;
+ case VEN_LEVEL_H263_70:
+ *eLevel = OMX_VIDEO_H263Level70;
+ break;
+ default:
+ *eLevel = OMX_VIDEO_H263LevelMax;
+ status = false;
+ break;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264)
+ {
+ switch(codec_profile.profile)
+ {
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+ *eProfile = OMX_VIDEO_AVCProfileBaseline;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+ *eProfile = OMX_VIDEO_AVCProfileMain;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+ *eProfile = OMX_VIDEO_AVCProfileHigh;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
+ *eProfile = OMX_VIDEO_AVCProfileExtended;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
+ *eProfile = OMX_VIDEO_AVCProfileHigh10;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
+ *eProfile = OMX_VIDEO_AVCProfileHigh422;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
+ *eProfile = OMX_VIDEO_AVCProfileHigh444;
+ break;
+ default:
+ *eProfile = OMX_VIDEO_AVCProfileMax;
+ status = false;
+ break;
+ }
+
+ if(!status)
+ {
+ return status;
+ }
+
+ switch(profile_level.level)
+ {
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
+ *eLevel = OMX_VIDEO_AVCLevel1;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
+ *eLevel = OMX_VIDEO_AVCLevel1b;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
+ *eLevel = OMX_VIDEO_AVCLevel11;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
+ *eLevel = OMX_VIDEO_AVCLevel12;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
+ *eLevel = OMX_VIDEO_AVCLevel13;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
+ *eLevel = OMX_VIDEO_AVCLevel2;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
+ *eLevel = OMX_VIDEO_AVCLevel21;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
+ *eLevel = OMX_VIDEO_AVCLevel22;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
+ *eLevel = OMX_VIDEO_AVCLevel3;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
+ *eLevel = OMX_VIDEO_AVCLevel31;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
+ *eLevel = OMX_VIDEO_AVCLevel32;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
+ *eLevel = OMX_VIDEO_AVCLevel4;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
+ *eLevel = OMX_VIDEO_AVCLevel41;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
+ *eLevel = OMX_VIDEO_AVCLevel42;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
+ *eLevel = OMX_VIDEO_AVCLevel5;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
+ *eLevel = OMX_VIDEO_AVCLevel51;
+ break;
+ default :
+ *eLevel = OMX_VIDEO_AVCLevelMax;
+ status = false;
+ break;
+ }
+ }
+ return status;
+}
+
+bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
+{
+ OMX_U32 new_profile = 0, new_level = 0;
+ unsigned const int *profile_tbl = NULL;
+ OMX_U32 mb_per_frame, mb_per_sec;
+ bool profile_level_found = false;
+
+ DEBUG_PRINT_LOW("\n Init profile table for respective codec");
+ //validate the ht,width,fps,bitrate and set the appropriate profile and level
+ if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4)
+ {
+ if(*eProfile == 0)
+ {
+ if(!m_profile_set)
+ {
+ *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ }
+ else
+ {
+ switch(codec_profile.profile)
+ {
+ case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
+ *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
+ break;
+ case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
+ *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ break;
+ default:
+ DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
+ return false;
+ }
+ }
+ }
+
+ if(*eLevel == 0 && !m_level_set)
+ {
+ *eLevel = OMX_VIDEO_MPEG4LevelMax;
+ }
+
+ if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple)
+ {
+ profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
+ }
+ else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
+ {
+ profile_tbl = (unsigned int const *)
+ (&mpeg4_profile_level_table[MPEG4_ASP_START]);
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile);
+ return false;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264)
+ {
+ if(*eProfile == 0)
+ {
+ if(!m_profile_set)
+ {
+ *eProfile = OMX_VIDEO_AVCProfileBaseline;
+ }
+ else
+ {
+ switch(codec_profile.profile)
+ {
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+ *eProfile = OMX_VIDEO_AVCProfileBaseline;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+ *eProfile = OMX_VIDEO_AVCProfileMain;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
+ *eProfile = OMX_VIDEO_AVCProfileExtended;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+ *eProfile = OMX_VIDEO_AVCProfileHigh;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
+ *eProfile = OMX_VIDEO_AVCProfileHigh10;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
+ *eProfile = OMX_VIDEO_AVCProfileHigh422;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
+ *eProfile = OMX_VIDEO_AVCProfileHigh444;
+ break;
+ default:
+ DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
+ return false;
+ }
+ }
+ }
+
+ if(*eLevel == 0 && !m_level_set)
+ {
+ *eLevel = OMX_VIDEO_AVCLevelMax;
+ }
+
+ if(*eProfile == OMX_VIDEO_AVCProfileBaseline)
+ {
+ profile_tbl = (unsigned int const *)h264_profile_level_table;
+ }
+ else if(*eProfile == OMX_VIDEO_AVCProfileHigh)
+ {
+ profile_tbl = (unsigned int const *)
+ (&h264_profile_level_table[H264_HP_START]);
+ }
+ else if(*eProfile == OMX_VIDEO_AVCProfileMain)
+ {
+ profile_tbl = (unsigned int const *)
+ (&h264_profile_level_table[H264_MP_START]);
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile);
+ return false;
+ }
+ }
+ else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263)
+ {
+ if(*eProfile == 0)
+ {
+ if(!m_profile_set)
+ {
+ *eProfile = OMX_VIDEO_H263ProfileBaseline;
+ }
+ else
+ {
+ switch(codec_profile.profile)
+ {
+ case VEN_PROFILE_H263_BASELINE:
+ *eProfile = OMX_VIDEO_H263ProfileBaseline;
+ break;
+ default:
+ DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
+ return false;
+ }
+ }
+ }
+
+ if(*eLevel == 0 && !m_level_set)
+ {
+ *eLevel = OMX_VIDEO_H263LevelMax;
+ }
+
+ if(*eProfile == OMX_VIDEO_H263ProfileBaseline)
+ {
+ profile_tbl = (unsigned int const *)h263_profile_level_table;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile);
+ return false;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("\n Invalid codec type");
+ return false;
+ }
+
+ mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
+ ((m_sVenc_cfg.input_width + 15)>> 4);
+
+ if((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4))
+ {
+ if(codec_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
+ profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
+ if(codec_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
+ profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
+ {
+ new_level = profile_level.level;
+ new_profile = codec_profile.profile;
+ return true;
+ }
+ }
+
+ mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
+
+ do{
+ if(mb_per_frame <= (int)profile_tbl[0])
+ {
+ if(mb_per_sec <= (int)profile_tbl[1])
+ {
+ if(m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2])
+ {
+ new_level = (int)profile_tbl[3];
+ new_profile = (int)profile_tbl[4];
+ profile_level_found = true;
+ DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level);
+ break;
+ }
+ }
+ }
+ profile_tbl = profile_tbl + 5;
+ }while(profile_tbl[0] != 0);
+
+ if (profile_level_found != true)
+ {
+ DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n");
+ return false;
+ }
+
+ if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
+ || (*eLevel == OMX_VIDEO_H263LevelMax))
+ {
+ *eLevel = new_level;
+ }
+ DEBUG_PRINT_HIGH("%s: Returning with eProfile = %lu"
+ "Level = %lu", __func__, *eProfile, *eLevel);
+
+ return true;
+}
+#ifdef _ANDROID_ICS_
+bool venc_dev::venc_set_meta_mode(bool mode)
+{
+ if(/*ioctl(m_nDriver_fd,VEN_IOCTL_SET_METABUFFER_MODE,&ioctl_msg) < */0)
+ {
+ DEBUG_PRINT_ERROR(" Set meta buffer mode failed");
+ return false;
+ }
+ return true;
+}
+#endif
diff --git a/mm-video/vidc/venc/test/camera_test.cpp b/mm-video/vidc/venc/test/camera_test.cpp
new file mode 100755
index 0000000..1c4f8ae
--- /dev/null
+++ b/mm-video/vidc/venc/test/camera_test.cpp
@@ -0,0 +1,93 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#include "camera_test.h"
+// #include "camera_class.h"
+
+EXTERN_C_START
+
+// static android::Camera* pCamera = NULL;
+
+int CameraTest_Initialize(int nFrameRate,
+ int nFrameWidth,
+ int nFrameHeight,
+ CameraPreviewCallback pfnPreviewCallback)
+{
+ int result = 0;
+
+// pCamera = new android::Camera;
+// if (!pCamera)
+// return 1;
+
+// pCamera->init_camera(nFrameWidth,
+// nFrameHeight,
+// nFrameRate,
+// pfnPreviewCallback);
+
+ return result;
+}
+
+int CameraTest_Run()
+{
+ int result = 0;
+
+// if (pCamera)
+// pCamera->startPreview();
+// else
+// return 1;
+
+ return result;
+}
+
+int CameraTest_ReleaseFrame(void* pPhys, void* pVirt)
+{
+ int result = 0;
+
+// if (pCamera)
+// pCamera->releaseFrame(pPhys, pVirt);
+// else
+// return 1;
+
+ return result;
+}
+
+int CameraTest_Exit()
+{
+ int result = 0;
+
+// if (pCamera)
+// {
+// pCamera->stopPreview();
+// delete pCamera;
+// }
+// pCamera = NULL;
+
+ return result;
+}
+
+
+EXTERN_C_END
diff --git a/mm-video/vidc/venc/test/fb_test.c b/mm-video/vidc/venc/test/fb_test.c
new file mode 100755
index 0000000..6bbe088
--- /dev/null
+++ b/mm-video/vidc/venc/test/fb_test.c
@@ -0,0 +1,48 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#include "fb_test.h"
+
+int FBTest_Initialize(int nFrameWidth,
+ int nFrameHeight)
+{
+ return 0;
+}
+int FBTest_DisplayImage(int nPmemFd, int nOffset)
+{
+ return 0;
+}
+
+int FBTest_Exit()
+{
+ return 0;
+}
+
+int FBTest_RunTest()
+{
+ return 0;
+}
diff --git a/mm-video/vidc/venc/test/queue.c b/mm-video/vidc/venc/test/queue.c
new file mode 100755
index 0000000..98c27da
--- /dev/null
+++ b/mm-video/vidc/venc/test/queue.c
@@ -0,0 +1,174 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#include "queue.h"
+
+int check_if_queue_empty ( unsigned int queuetocheck, void* queuecontext )
+{
+ struct video_queue_context *ptr_q = NULL;
+ /*
+ * queuetocheck - 0 command queue
+ * queuetocheck - 1 data queue
+ */
+ if ( queuecontext == NULL || (queuetocheck > 1 ) )
+ {
+ return 1;
+ }
+ ptr_q = (struct video_queue_context *)queuecontext;
+
+ if (queuetocheck == 0)
+ {
+ if (ptr_q->read_comq == ptr_q->write_comq)
+ {
+ return 1;
+ }
+ }
+ else if (queuetocheck == 1)
+ {
+ if (ptr_q->write_dataq == ptr_q->read_dataq)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+
+struct video_msgq * queue_get_cmd (void* queuecontext )
+{
+ struct video_queue_context *ptr_q = NULL;
+ struct video_msgq *pitem = NULL;
+
+ if( NULL == queuecontext )
+ {
+ printf("\n queue_get_cmd: Invalid Input parameter\n");
+ return NULL;
+ }
+
+ ptr_q = (struct video_queue_context *)queuecontext;
+
+ /* Wait on the semaphore till it is released */
+ sem_wait(&ptr_q->sem_message);
+
+ /* Lock the mutex to protect the critical section */
+ pthread_mutex_lock(&ptr_q->mutex);
+
+ if (ptr_q->read_comq != ptr_q->write_comq)
+ {
+ pitem = &ptr_q->ptr_cmdq [ptr_q->read_comq];
+ ptr_q->read_comq = (ptr_q->read_comq + 1) % \
+ ptr_q->commandq_size;
+ }
+ else if (ptr_q->write_dataq != ptr_q->read_dataq)
+ {
+ pitem = &ptr_q->ptr_dataq [ptr_q->read_dataq];
+ ptr_q->read_dataq = (ptr_q->read_dataq + 1) % \
+ ptr_q->dataq_size;
+ }
+
+ /* Unlock the mutex to release the critical section */
+ pthread_mutex_unlock(&ptr_q->mutex);
+
+ return pitem;
+}
+
+
+int queue_post_cmdq ( void* queuecontext,
+ struct video_msgq *pitem
+ )
+{
+ struct video_queue_context *ptr_q = NULL;
+
+ if (pitem == NULL || queuecontext == NULL)
+ {
+ return -1;
+ }
+ ptr_q = (struct video_queue_context *)queuecontext;
+
+ /* Lock the mutex to protect the critical section */
+ pthread_mutex_lock(&ptr_q->mutex);
+
+ if ((ptr_q->write_comq + 1) % ptr_q->commandq_size == ptr_q->read_comq)
+ {
+ printf("\n QUEUE is FULL");
+ return 0;
+ }
+ else
+ {
+ /* Store the command in the Message Queue & increment write offset */
+ memcpy ( &ptr_q->ptr_cmdq [ptr_q->write_comq],pitem, \
+ sizeof (struct video_msgq));
+ ptr_q->write_comq = (ptr_q->write_comq + 1) % ptr_q->commandq_size;
+ }
+
+ /* Unlock the mutex to release the critical section */
+ pthread_mutex_unlock(&ptr_q->mutex);
+
+ /* Post the semaphore */
+ sem_post(&ptr_q->sem_message);
+ return 1;
+}
+
+
+int queue_post_dataq ( void *queuecontext,
+ struct video_msgq *pitem
+ )
+{
+ struct video_queue_context *ptr_q = NULL;
+
+ if (pitem == NULL || queuecontext == NULL)
+ {
+ return -1;
+ }
+ ptr_q = (struct video_queue_context *)queuecontext;
+
+ /* Lock the mutex to protect the critical section */
+ pthread_mutex_lock(&ptr_q->mutex);
+
+ if ((ptr_q->write_dataq + 1) % ptr_q->dataq_size == ptr_q->read_dataq)
+ {
+ printf("\n QUEUE is FULL");
+ return 0;
+ }
+ else
+ {
+ /* Store the command in the Message Queue & increment write offset */
+ memcpy ( &ptr_q->ptr_dataq [ptr_q->write_dataq],pitem, \
+ sizeof (struct video_msgq));
+ ptr_q->write_dataq = (ptr_q->write_dataq + 1) % ptr_q->dataq_size;
+ }
+
+ /* Unlock the mutex to release the critical section */
+ pthread_mutex_unlock(&ptr_q->mutex);
+
+ /* Post the semaphore */
+ sem_post(&ptr_q->sem_message);
+ return 1;
+
+}
diff --git a/mm-video/vidc/venc/test/venc_test.cpp b/mm-video/vidc/venc/test/venc_test.cpp
new file mode 100755
index 0000000..c525aab
--- /dev/null
+++ b/mm-video/vidc/venc/test/venc_test.cpp
@@ -0,0 +1,2333 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+/*============================================================================
+ V E N C _ T E S T. C P P
+
+DESCRIPTION
+
+ This is the OMX test app .
+
+REFERENCES
+
+============================================================================*/
+
+//usage
+// FILE QVGA MP4 24 384000 100 enc_qvga.yuv QVGA_24.m4v
+// FILE QCIF MP4 15 96000 0 foreman.qcif.yuv output_qcif.m4v
+// FILE VGA MP4 24 1200000 218 enc_vga.yuv vga_output.m4v
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+//#include <sys/time.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include <limits.h>
+#include <string.h>
+//#include <sys/stat.h>
+#include "OMX_QCOMExtns.h"
+#include "OMX_Core.h"
+
+#define QCOM_EXT 1
+
+#include "OMX_Core.h"
+#include "OMX_Video.h"
+#include "OMX_Component.h"
+#include "camera_test.h"
+#include "fb_test.h"
+#include "venc_util.h"
+#include "extra_data_handler.h"
+#ifdef USE_ION
+#include <ion_msm.h>
+#endif
+
+//////////////////////////
+// MACROS
+//////////////////////////
+
+#define CHK(result) if (result != OMX_ErrorNone) { E("*************** error *************"); exit(0); }
+#define TEST_LOG
+#ifdef VENC_SYSLOG
+#include "cutils/log.h"
+/// Debug message macro
+#define D(fmt, ...) LOGE("venc_test Debug %s::%d "fmt"\n", \
+ __FUNCTION__, __LINE__, \
+ ## __VA_ARGS__)
+
+/// Error message macro
+#define E(fmt, ...) LOGE("venc_test Error %s::%d "fmt"\n", \
+ __FUNCTION__, __LINE__, \
+ ## __VA_ARGS__)
+
+#else
+ #ifdef TEST_LOG
+ #define D(fmt, ...) fprintf(stderr, "venc_test Debug %s::%d "fmt"\n", \
+ __FUNCTION__, __LINE__, \
+ ## __VA_ARGS__)
+
+ /// Error message macro
+ #define E(fmt, ...) fprintf(stderr, "venc_test Error %s::%d "fmt"\n", \
+ __FUNCTION__, __LINE__, \
+ ## __VA_ARGS__)
+ #else
+ #define D(fmt, ...)
+ #define E(fmt, ...)
+ #endif
+
+#endif
+
+//////////////////////////
+// CONSTANTS
+//////////////////////////
+static const int MAX_MSG = 100;
+//#warning do not hardcode these use port definition
+static const int PORT_INDEX_IN = 0;
+static const int PORT_INDEX_OUT = 1;
+
+static const int NUM_IN_BUFFERS = 10;
+static const int NUM_OUT_BUFFERS = 10;
+
+unsigned int num_in_buffers = 0;
+unsigned int num_out_buffers = 0;
+
+//////////////////////////
+/* MPEG4 profile and level table*/
+static const unsigned int mpeg4_profile_level_table[][5]=
+{
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
+ {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
+ {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
+ {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
+ {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
+ {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
+ {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
+ {0,0,0,0,0},
+
+ {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {0,0,0,0,0},
+};
+
+/* H264 profile and level table*/
+static const unsigned int h264_profile_level_table[][5]=
+{
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
+ {0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
+ {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
+ {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
+ {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
+ {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
+ {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
+ {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
+ {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
+ {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
+ {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
+ {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
+ {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
+ {0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
+ {0,0,0,0,0}
+
+};
+
+/* H263 profile and level table*/
+static const unsigned int h263_profile_level_table[][5]=
+{
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
+ {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
+ {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
+ {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
+ {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
+ {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
+ {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
+ {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
+ {0,0,0,0,0}
+};
+
+#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
+#define FractionToQ16(q,num,den) { OMX_U32 power; Log2(den,power); q = num << (16 - power); }
+
+//////////////////////////
+// TYPES
+//////////////////////////
+struct ProfileType
+{
+ OMX_VIDEO_CODINGTYPE eCodec;
+ OMX_VIDEO_MPEG4LEVELTYPE eLevel;
+ OMX_VIDEO_CONTROLRATETYPE eControlRate;
+ OMX_VIDEO_AVCSLICEMODETYPE eSliceMode;
+ OMX_U32 nFrameWidth;
+ OMX_U32 nFrameHeight;
+ OMX_U32 nFrameBytes;
+#ifdef BADGER
+ OMX_U32 nFramestride;
+ OMX_U32 nFrameScanlines;
+ OMX_U32 nFrameRead;
+#endif
+ OMX_U32 nBitrate;
+ float nFramerate;
+ char* cInFileName;
+ char* cOutFileName;
+ OMX_U32 nUserProfile;
+};
+
+enum MsgId
+{
+ MSG_ID_OUTPUT_FRAME_DONE,
+ MSG_ID_INPUT_FRAME_DONE,
+ MSG_ID_MAX
+};
+union MsgData
+{
+ struct
+ {
+ OMX_BUFFERHEADERTYPE* pBuffer;
+ } sBitstreamData;
+};
+struct Msg
+{
+ MsgId id;
+ MsgData data;
+};
+struct MsgQ
+{
+ Msg q[MAX_MSG];
+ int head;
+ int size;
+};
+
+enum Mode
+{
+ MODE_PREVIEW,
+ MODE_DISPLAY,
+ MODE_PROFILE,
+ MODE_FILE_ENCODE,
+ MODE_LIVE_ENCODE
+};
+
+enum ResyncMarkerType
+{
+ RESYNC_MARKER_NONE, ///< No resync marker
+ RESYNC_MARKER_BYTE, ///< BYTE Resync marker for MPEG4, H.264
+ RESYNC_MARKER_MB, ///< MB resync marker for MPEG4, H.264
+ RESYNC_MARKER_GOB ///< GOB resync marker for H.263
+};
+
+union DynamicConfigData
+{
+ OMX_VIDEO_CONFIG_BITRATETYPE bitrate;
+ OMX_CONFIG_FRAMERATETYPE framerate;
+ QOMX_VIDEO_INTRAPERIODTYPE intraperiod;
+ OMX_CONFIG_INTRAREFRESHVOPTYPE intravoprefresh;
+ OMX_CONFIG_ROTATIONTYPE rotation;
+ float f_framerate;
+};
+
+struct DynamicConfig
+{
+ bool pending;
+ unsigned frame_num;
+ OMX_INDEXTYPE config_param;
+ union DynamicConfigData config_data;
+};
+
+#ifdef USE_ION
+struct enc_ion
+{
+ int ion_device_fd;
+ struct ion_allocation_data alloc_data;
+ struct ion_fd_data ion_alloc_fd;
+};
+#endif
+
+//////////////////////////
+// MODULE VARS
+//////////////////////////
+static pthread_mutex_t m_mutex;
+static pthread_cond_t m_signal;
+static MsgQ m_sMsgQ;
+
+//#warning determine how many buffers we really have
+OMX_STATETYPE m_eState = OMX_StateInvalid;
+OMX_COMPONENTTYPE m_sComponent;
+OMX_HANDLETYPE m_hHandle = NULL;
+OMX_BUFFERHEADERTYPE* m_pOutBuffers[NUM_OUT_BUFFERS] = {NULL};
+OMX_BUFFERHEADERTYPE* m_pInBuffers[NUM_IN_BUFFERS] = {NULL};
+OMX_BOOL m_bInFrameFree[NUM_IN_BUFFERS];
+
+ProfileType m_sProfile;
+
+static int m_nFramePlay = 0;
+static int m_eMode = MODE_PREVIEW;
+static int m_nInFd = -1;
+static int m_nOutFd = -1;
+static int m_nTimeStamp = 0;
+static int m_nFrameIn = 0; // frames pushed to encoder
+static int m_nFrameOut = 0; // frames returned by encoder
+static int m_nAVCSliceMode = 0;
+static bool m_bWatchDogKicked = false;
+FILE *m_pDynConfFile = NULL;
+static struct DynamicConfig dynamic_config;
+
+/* Statistics Logging */
+static long long tot_bufsize = 0;
+int ebd_cnt=0, fbd_cnt=0;
+
+#ifdef USE_ION
+static const char* PMEM_DEVICE = "/dev/ion";
+#elif MAX_RES_720P
+static const char* PMEM_DEVICE = "/dev/pmem_adsp";
+#elif MAX_RES_1080P_EBI
+static const char* PMEM_DEVICE = "/dev/pmem_adsp";
+#elif MAX_RES_1080P
+static const char* PMEM_DEVICE = "/dev/pmem_smipool";
+#else
+#error PMEM_DEVICE cannot be determined.
+#endif
+
+#ifdef USE_ION
+struct enc_ion ion_data;
+#endif
+//////////////////////////
+// MODULE FUNCTIONS
+//////////////////////////
+
+void* PmemMalloc(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, int nSize)
+{
+ void *pvirt = NULL;
+ int rc = 0;
+
+ if (!pMem)
+ return NULL;
+
+#ifdef USE_ION
+ ion_data.ion_device_fd = open (PMEM_DEVICE,O_RDONLY/*|O_DSYNC*/);
+ if(ion_data.ion_device_fd < 0)
+ {
+ E("\nERROR: ION Device open() Failed");
+ return NULL;
+ }
+ nSize = (nSize + 4095) & (~4095);
+ ion_data.alloc_data.len = nSize;
+ ion_data.alloc_data.flags = 0x1 << ION_CP_MM_HEAP_ID;
+ ion_data.alloc_data.align = 4096;
+
+ rc = ioctl(ion_data.ion_device_fd,ION_IOC_ALLOC,&ion_data.alloc_data);
+ if(rc || !ion_data.alloc_data.handle) {
+ E("\n ION ALLOC memory failed ");
+ ion_data.alloc_data.handle=NULL;
+ return NULL;
+ }
+
+ ion_data.ion_alloc_fd.handle = ion_data.alloc_data.handle;
+ rc = ioctl(ion_data.ion_device_fd,ION_IOC_MAP,&ion_data.ion_alloc_fd);
+ if(rc) {
+ E("\n ION MAP failed ");
+ ion_data.ion_alloc_fd.fd =-1;
+ ion_data.ion_alloc_fd.fd =-1;
+ return NULL;
+ }
+ pMem->pmem_fd = ion_data.ion_alloc_fd.fd;
+#else
+ pMem->pmem_fd = open(PMEM_DEVICE, O_RDWR);
+ if ((int)(pMem->pmem_fd) < 0)
+ return NULL;
+ nSize = (nSize + 4095) & (~4095);
+#endif
+ pMem->offset = 0;
+ pvirt = mmap(NULL, nSize,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, pMem->pmem_fd, pMem->offset);
+ if (pvirt == (void*) MAP_FAILED)
+ {
+ close(pMem->pmem_fd);
+ pMem->pmem_fd = -1;
+#ifdef USE_ION
+ if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE,
+ &ion_data.alloc_data.handle)) {
+ E("ion recon buffer free failed");
+ }
+ ion_data.alloc_data.handle = NULL;
+ ion_data.ion_alloc_fd.fd =-1;
+ close(ion_data.ion_device_fd);
+ ion_data.ion_device_fd =-1;
+#endif
+ return NULL;
+ }
+ D("allocated pMem->fd = %d pvirt=0x%x, pMem->phys=0x%x, size = %d", pMem->pmem_fd,
+ pvirt, pMem->offset, nSize);
+ return pvirt;
+}
+
+int PmemFree(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, void* pvirt, int nSize)
+{
+ if (!pMem || !pvirt)
+ return -1;
+
+ nSize = (nSize + 4095) & (~4095);
+ munmap(pvirt, nSize);
+ close(pMem->pmem_fd);
+ pMem->pmem_fd = -1;
+#ifdef USE_ION
+ if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE,
+ &ion_data.alloc_data.handle)) {
+ E("ion recon buffer free failed");
+ }
+ ion_data.alloc_data.handle = NULL;
+ ion_data.ion_alloc_fd.fd =-1;
+ close(ion_data.ion_device_fd);
+ ion_data.ion_device_fd =-1;
+#endif
+ return 0;
+}
+void PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement)
+{
+ printf("id (%d)\n",
+ framePackingArrangement.id);
+ printf("cancel_flag (%d)\n",
+ framePackingArrangement.cancel_flag);
+ printf("type (%d)\n",
+ framePackingArrangement.type);
+ printf("quincunx_sampling_flag (%d)\n",
+ framePackingArrangement.quincunx_sampling_flag);
+ printf("content_interpretation_type (%d)\n",
+ framePackingArrangement.content_interpretation_type);
+ printf("spatial_flipping_flag (%d)\n",
+ framePackingArrangement.spatial_flipping_flag);
+ printf("frame0_flipped_flag (%d)\n",
+ framePackingArrangement.frame0_flipped_flag);
+ printf("field_views_flag (%d)\n",
+ framePackingArrangement.field_views_flag);
+ printf("current_frame_is_frame0_flag (%d)\n",
+ framePackingArrangement.current_frame_is_frame0_flag);
+ printf("frame0_self_contained_flag (%d)\n",
+ framePackingArrangement.frame0_self_contained_flag);
+ printf("frame1_self_contained_flag (%d)\n",
+ framePackingArrangement.frame1_self_contained_flag);
+ printf("frame0_grid_position_x (%d)\n",
+ framePackingArrangement.frame0_grid_position_x);
+ printf("frame0_grid_position_y (%d)\n",
+ framePackingArrangement.frame0_grid_position_y);
+ printf("frame1_grid_position_x (%d)\n",
+ framePackingArrangement.frame1_grid_position_x);
+ printf("frame1_grid_position_y (%d)\n",
+ framePackingArrangement.frame1_grid_position_y);
+ printf("reserved_byte (%d)\n",
+ framePackingArrangement.reserved_byte);
+ printf("repetition_period (%d)\n",
+ framePackingArrangement.repetition_period);
+ printf("extension_flag (%d)\n",
+ framePackingArrangement.extension_flag);
+}
+void SetState(OMX_STATETYPE eState)
+{
+#define GOTO_STATE(eState) \
+ case eState: \
+ { \
+ D("Going to state " # eState"..."); \
+ OMX_SendCommand(m_hHandle, \
+ OMX_CommandStateSet, \
+ (OMX_U32) eState, \
+ NULL); \
+ while (m_eState != eState) \
+ { \
+ sleep(1); \
+ } \
+ D("Now in state " # eState); \
+ break; \
+ }
+
+ switch (eState)
+ {
+ GOTO_STATE(OMX_StateLoaded);
+ GOTO_STATE(OMX_StateIdle);
+ GOTO_STATE(OMX_StateExecuting);
+ GOTO_STATE(OMX_StateInvalid);
+ GOTO_STATE(OMX_StateWaitForResources);
+ GOTO_STATE(OMX_StatePause);
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+OMX_ERRORTYPE ConfigureEncoder()
+{
+ OMX_ERRORTYPE result = OMX_ErrorNone;
+ unsigned const int *profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
+ OMX_U32 mb_per_sec, mb_per_frame;
+ bool profile_level_found = false;
+ OMX_U32 eProfile,eLevel;
+
+ OMX_PARAM_PORTDEFINITIONTYPE portdef; // OMX_IndexParamPortDefinition
+#ifdef QCOM_EXT
+ OMX_QCOM_PARAM_PORTDEFINITIONTYPE qPortDefnType;
+#endif
+ portdef.nPortIndex = (OMX_U32) 0; // input
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamPortDefinition,
+ &portdef);
+ E("\n OMX_IndexParamPortDefinition Get Paramter on input port");
+ CHK(result);
+ portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth;
+ portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight;
+
+ E ("\n Height %d width %d bit rate %d",portdef.format.video.nFrameHeight
+ ,portdef.format.video.nFrameWidth,portdef.format.video.nBitrate);
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamPortDefinition,
+ &portdef);
+ E("\n OMX_IndexParamPortDefinition Set Paramter on input port");
+ CHK(result);
+ // once more to get proper buffer size
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamPortDefinition,
+ &portdef);
+ E("\n OMX_IndexParamPortDefinition Get Paramter on input port, 2nd pass");
+ CHK(result);
+ // update size accordingly
+ m_sProfile.nFrameBytes = portdef.nBufferSize;
+ portdef.nPortIndex = (OMX_U32) 1; // output
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamPortDefinition,
+ &portdef);
+ E("\n OMX_IndexParamPortDefinition Get Paramter on output port");
+ CHK(result);
+ portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth;
+ portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight;
+ portdef.format.video.nBitrate = m_sProfile.nBitrate;
+ FractionToQ16(portdef.format.video.xFramerate,(int) (m_sProfile.nFramerate * 2),2);
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamPortDefinition,
+ &portdef);
+ E("\n OMX_IndexParamPortDefinition Set Paramter on output port");
+ CHK(result);
+
+#ifdef QCOM_EXT
+
+qPortDefnType.nPortIndex = PORT_INDEX_IN;
+qPortDefnType.nMemRegion = OMX_QCOM_MemRegionEBI1;
+qPortDefnType.nSize = sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
+
+result = OMX_SetParameter(m_hHandle,
+ (OMX_INDEXTYPE)OMX_QcomIndexPortDefn,
+ &qPortDefnType);
+
+#endif
+ if (!m_sProfile.nUserProfile) // profile not set by user, go ahead with table calculation
+ {
+ //validate the ht,width,fps,bitrate and set the appropriate profile and level
+ if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
+ {
+ profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
+ }
+ else if(m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
+ {
+ profile_tbl = (unsigned int const *)h264_profile_level_table;
+ }
+ else if(m_sProfile.eCodec == OMX_VIDEO_CodingH263)
+ {
+ profile_tbl = (unsigned int const *)h263_profile_level_table;
+ }
+
+ mb_per_frame = ((m_sProfile.nFrameHeight+15)>>4)*
+ ((m_sProfile.nFrameWidth+15)>>4);
+
+ mb_per_sec = mb_per_frame*(m_sProfile.nFramerate);
+
+ do{
+ if(mb_per_frame <= (int)profile_tbl[0])
+ {
+ if(mb_per_sec <= (int)profile_tbl[1])
+ {
+ if(m_sProfile.nBitrate <= (int)profile_tbl[2])
+ {
+ eLevel = (int)profile_tbl[3];
+ eProfile = (int)profile_tbl[4];
+ E("\n profile/level found: %d/%d\n",eProfile/eLevel);
+ profile_level_found = true;
+ break;
+ }
+ }
+ }
+ profile_tbl = profile_tbl + 5;
+ }while(profile_tbl[0] != 0);
+
+ if ( profile_level_found != true )
+ {
+ E("\n Error: Unsupported profile/level\n");
+ return OMX_ErrorNone;
+ }
+ }
+ else // Profile set by user!
+ {
+ eProfile = m_sProfile.nUserProfile;
+ eLevel = 0;
+ }
+ if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
+ {
+ D("Configuring H263...");
+
+ OMX_VIDEO_PARAM_H263TYPE h263;
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamVideoH263,
+ &h263);
+ CHK(result);
+ h263.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ h263.nPFrames = m_sProfile.nFramerate * 2 - 1; // intra period
+ h263.nBFrames = 0;
+ h263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile;
+ h263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel;
+ h263.bPLUSPTYPEAllowed = OMX_FALSE;
+ h263.nAllowedPictureTypes = 2;
+ h263.bForceRoundingTypeToZero = OMX_TRUE;
+ h263.nPictureHeaderRepetition = 0;
+ h263.nGOBHeaderInterval = 1;
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamVideoH263,
+ &h263);
+ }
+ else
+ {
+ D("Configuring MP4/H264...");
+
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE profileLevel; // OMX_IndexParamVideoProfileLevelCurrent
+ profileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ profileLevel.eProfile = eProfile;
+ profileLevel.eLevel = eLevel;
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamVideoProfileLevelCurrent,
+ &profileLevel);
+ E("\n OMX_IndexParamVideoProfileLevelCurrent Set Paramter port");
+ CHK(result);
+ //profileLevel.eLevel = (OMX_U32) m_sProfile.eLevel;
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamVideoProfileLevelCurrent,
+ &profileLevel);
+ E("\n OMX_IndexParamVideoProfileLevelCurrent Get Paramter port");
+ D ("\n Profile = %d level = %d",profileLevel.eProfile,profileLevel.eLevel);
+ CHK(result);
+
+ if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
+ {
+ OMX_VIDEO_PARAM_MPEG4TYPE mp4; // OMX_IndexParamVideoMpeg4
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamVideoMpeg4,
+ &mp4);
+ CHK(result);
+ mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ mp4.nTimeIncRes = 1000;
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamVideoMpeg4,
+ &mp4);
+ CHK(result);
+ }
+ }
+ if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
+ {
+#if 1
+/////////////C A B A C ///A N D/////D E B L O C K I N G /////////////////
+
+ OMX_VIDEO_PARAM_AVCTYPE avcdata;
+ avcdata.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamVideoAvc,
+ &avcdata);
+ CHK(result);
+// TEST VALUES (CHANGE FOR DIFF CONFIG's)
+ avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
+// avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisable;
+// avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisableSliceBoundary;
+ avcdata.bEntropyCodingCABAC = OMX_FALSE;
+// avcdata.bEntropyCodingCABAC = OMX_TRUE;
+ avcdata.nCabacInitIdc = 1;
+///////////////////////////////////////////////
+
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamVideoAvc,
+ &avcdata);
+ CHK(result);
+
+/////////////C A B A C ///A N D/////D E B L O C K I N G /////////////////
+#endif
+ }
+
+ OMX_VIDEO_PARAM_BITRATETYPE bitrate; // OMX_IndexParamVideoBitrate
+ bitrate.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamVideoBitrate,
+ &bitrate);
+ E("\n OMX_IndexParamVideoBitrate Get Paramter port");
+ CHK(result);
+ bitrate.eControlRate = m_sProfile.eControlRate;
+ bitrate.nTargetBitrate = m_sProfile.nBitrate;
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamVideoBitrate,
+ &bitrate);
+ E("\n OMX_IndexParamVideoBitrate Set Paramter port");
+ CHK(result);
+
+ OMX_VIDEO_PARAM_PORTFORMATTYPE framerate; // OMX_IndexParamVidePortFormat
+ framerate.nPortIndex = 0;
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamVideoPortFormat,
+ &framerate);
+ E("\n OMX_IndexParamVideoPortFormat Get Paramter port");
+ CHK(result);
+ FractionToQ16(framerate.xFramerate,(int) (m_sProfile.nFramerate * 2),2);
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamVideoPortFormat,
+ &framerate);
+ E("\n OMX_IndexParamVideoPortFormat Set Paramter port");
+ CHK(result);
+
+#if 1
+///////////////////I N T R A P E R I O D ///////////////////
+
+ QOMX_VIDEO_INTRAPERIODTYPE intra;
+
+ intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
+ result = OMX_GetConfig(m_hHandle,
+ (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod,
+ (OMX_PTR) &intra);
+
+ if (result == OMX_ErrorNone)
+ {
+ intra.nPFrames = (OMX_U32) (2 * m_sProfile.nFramerate - 1); //setting I
+ //frame interval to
+ //2 x framerate
+ intra.nIDRPeriod = 1; //every I frame is an IDR
+ intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ result = OMX_SetConfig(m_hHandle,
+ (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod,
+ (OMX_PTR) &intra);
+ }
+ else
+ {
+ E("failed to get state", 0, 0, 0);
+ }
+
+
+///////////////////I N T R A P E R I O D ///////////////////
+#endif
+
+#if 1
+///////////////////E R R O R C O R R E C T I O N ///////////////////
+
+ ResyncMarkerType eResyncMarkerType = RESYNC_MARKER_NONE;
+ unsigned long int nResyncMarkerSpacing = 0;
+ OMX_BOOL enableHEC = OMX_FALSE;
+
+//For Testing ONLY
+ if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
+ {
+// MPEG4
+// eResyncMarkerType = RESYNC_MARKER_BYTE;
+// nResyncMarkerSpacing = 1920;
+ eResyncMarkerType = RESYNC_MARKER_MB;
+ nResyncMarkerSpacing = 50;
+ enableHEC = OMX_TRUE;
+ }
+ else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
+ {
+//H263
+ eResyncMarkerType = RESYNC_MARKER_GOB;
+ nResyncMarkerSpacing = 0;
+ }
+ else if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
+ {
+//H264
+// eResyncMarkerType = RESYNC_MARKER_BYTE;
+// nResyncMarkerSpacing = 1920;
+
+ //nResyncMarkerSpacing sets the slice size in venc_set_multislice_cfg
+ //
+ //As of 9/24/10, it is known that the firmware has a bitstream
+ //corruption issue when RateControl and multislice are enabled for 720P
+ //So, disabling multislice for 720P when ratecontrol is enabled until
+ //the firmware issue is resolved.
+
+ if ( ( (m_sProfile.nFrameWidth == 1280) && (m_sProfile.nFrameHeight = 720) ) &&
+ (m_sProfile.eControlRate != OMX_Video_ControlRateDisable) )
+ {
+ eResyncMarkerType = RESYNC_MARKER_NONE;
+ nResyncMarkerSpacing = 0;
+ }
+ else
+ {
+ eResyncMarkerType = RESYNC_MARKER_MB;
+ nResyncMarkerSpacing = 50;
+ }
+ }
+
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrection; //OMX_IndexParamVideoErrorCorrection
+ errorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
+ result = OMX_GetParameter(m_hHandle,
+ (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection,
+ (OMX_PTR) &errorCorrection);
+
+ errorCorrection.bEnableRVLC = OMX_FALSE;
+ errorCorrection.bEnableDataPartitioning = OMX_FALSE;
+
+ if ((eResyncMarkerType == RESYNC_MARKER_BYTE) &&
+ (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)){
+ errorCorrection.bEnableResync = OMX_TRUE;
+ errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing;
+ errorCorrection.bEnableHEC = enableHEC;
+ }
+ else if ((eResyncMarkerType == RESYNC_MARKER_BYTE) &&
+ (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)){
+ errorCorrection.bEnableResync = OMX_TRUE;
+ errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing;
+ }
+ else if ((eResyncMarkerType == RESYNC_MARKER_GOB) &&
+ (m_sProfile.eCodec == OMX_VIDEO_CodingH263)){
+ errorCorrection.bEnableResync = OMX_FALSE;
+ errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing;
+ errorCorrection.bEnableDataPartitioning = OMX_TRUE;
+ }
+
+ result = OMX_SetParameter(m_hHandle,
+ (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection,
+ (OMX_PTR) &errorCorrection);
+ CHK(result);
+
+ if (eResyncMarkerType == RESYNC_MARKER_MB){
+ if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC){
+ OMX_VIDEO_PARAM_AVCTYPE avcdata;
+ avcdata.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamVideoAvc,
+ (OMX_PTR) &avcdata);
+ CHK(result);
+ if (result == OMX_ErrorNone)
+ {
+ avcdata.nSliceHeaderSpacing = nResyncMarkerSpacing;
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamVideoAvc,
+ (OMX_PTR) &avcdata);
+ CHK(result);
+
+ }
+ }
+ else if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4){
+ OMX_VIDEO_PARAM_MPEG4TYPE mp4;
+ mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamVideoMpeg4,
+ (OMX_PTR) &mp4);
+ CHK(result);
+
+ if (result == OMX_ErrorNone)
+ {
+ mp4.nSliceHeaderSpacing = nResyncMarkerSpacing;
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamVideoMpeg4,
+ (OMX_PTR) &mp4);
+ CHK(result);
+ }
+ }
+ }
+
+///////////////////E R R O R C O R R E C T I O N ///////////////////
+#endif
+
+#if 1
+///////////////////I N T R A R E F R E S H///////////////////
+ bool bEnableIntraRefresh = OMX_TRUE;
+
+ if (result == OMX_ErrorNone)
+ {
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE ir; // OMX_IndexParamVideoIntraRefresh
+ ir.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
+ result = OMX_GetParameter(m_hHandle,
+ OMX_IndexParamVideoIntraRefresh,
+ (OMX_PTR) &ir);
+ if (result == OMX_ErrorNone)
+ {
+ if (bEnableIntraRefresh)
+ {
+ ir.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
+ ir.nCirMBs = 5;
+ result = OMX_SetParameter(m_hHandle,
+ OMX_IndexParamVideoIntraRefresh,
+ (OMX_PTR) &ir);
+ CHK(result);
+ }
+ }
+ }
+#endif
+#if 1
+///////////////////FRAMEPACKING DATA///////////////////
+ OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement;
+ FILE *m_pConfigFile;
+ char m_configFilename [128] = "/data/configFile.cfg";
+ memset(&framePackingArrangement, 0, sizeof(framePackingArrangement));
+ m_pConfigFile = fopen(m_configFilename, "r");
+ if (m_pConfigFile != NULL)
+ {
+ //read all frame packing data
+ framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
+ int totalSizeToRead = FRAME_PACK_SIZE * sizeof(OMX_U32);
+ char *pFramePack = (char *) &(framePackingArrangement.id);
+ while ( ( (fscanf(m_pConfigFile, "%d", pFramePack)) != EOF ) &&
+ (totalSizeToRead != 0) )
+ {
+ //printf("Addr = %p, Value read = %d, sizeToRead remaining=%d\n",
+ // pFramePack, *pFramePack, totalSizeToRead);
+ pFramePack += sizeof(OMX_U32);
+ totalSizeToRead -= sizeof(OMX_U32);
+ }
+ //close the file.
+ fclose(m_pConfigFile);
+
+ printf("Frame Packing data from config file:\n");
+ PrintFramePackArrangement(framePackingArrangement);
+ }
+ else
+ {
+ D("\n Config file does not exist or could not be opened.");
+ //set the default values
+ framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
+ framePackingArrangement.id = 123;
+ framePackingArrangement.cancel_flag = false;
+ framePackingArrangement.type = 3;
+ framePackingArrangement.quincunx_sampling_flag = false;
+ framePackingArrangement.content_interpretation_type = 0;
+ framePackingArrangement.spatial_flipping_flag = true;
+ framePackingArrangement.frame0_flipped_flag = false;
+ framePackingArrangement.field_views_flag = false;
+ framePackingArrangement.current_frame_is_frame0_flag = false;
+ framePackingArrangement.frame0_self_contained_flag = true;
+ framePackingArrangement.frame1_self_contained_flag = false;
+ framePackingArrangement.frame0_grid_position_x = 3;
+ framePackingArrangement.frame0_grid_position_y = 15;
+ framePackingArrangement.frame1_grid_position_x = 11;
+ framePackingArrangement.frame1_grid_position_y = 7;
+ framePackingArrangement.reserved_byte = 0;
+ framePackingArrangement.repetition_period = 16381;
+ framePackingArrangement.extension_flag = false;
+
+ printf("Frame Packing Defaults :\n");
+ PrintFramePackArrangement(framePackingArrangement);
+ }
+ result = OMX_SetConfig(m_hHandle,
+ (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement,
+ (OMX_PTR) &framePackingArrangement);
+ CHK(result);
+
+//////////////////////OMX_VIDEO_PARAM_INTRAREFRESHTYPE///////////////////
+#endif
+
+ OMX_CONFIG_FRAMERATETYPE enc_framerate; // OMX_IndexConfigVideoFramerate
+ enc_framerate.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
+ result = OMX_GetConfig(m_hHandle,
+ OMX_IndexConfigVideoFramerate,
+ &enc_framerate);
+ CHK(result);
+ FractionToQ16(enc_framerate.xEncodeFramerate,(int) (m_sProfile.nFramerate * 2),2);
+ result = OMX_SetConfig(m_hHandle,
+ OMX_IndexConfigVideoFramerate,
+ &enc_framerate);
+ CHK(result);
+ return OMX_ErrorNone;
+}
+////////////////////////////////////////////////////////////////////////////////
+void SendMessage(MsgId id, MsgData* data)
+{
+ pthread_mutex_lock(&m_mutex);
+ if (m_sMsgQ.size >= MAX_MSG)
+ {
+ E("main msg m_sMsgQ is full");
+ return;
+ }
+ m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].id = id;
+ if (data)
+ m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].data = *data;
+ ++m_sMsgQ.size;
+ pthread_cond_signal(&m_signal);
+ pthread_mutex_unlock(&m_mutex);
+}
+////////////////////////////////////////////////////////////////////////////////
+void PopMessage(Msg* msg)
+{
+ pthread_mutex_lock(&m_mutex);
+ while (m_sMsgQ.size == 0)
+ {
+ pthread_cond_wait(&m_signal, &m_mutex);
+ }
+ *msg = m_sMsgQ.q[m_sMsgQ.head];
+ --m_sMsgQ.size;
+ m_sMsgQ.head = (m_sMsgQ.head + 1) % MAX_MSG;
+ pthread_mutex_unlock(&m_mutex);
+}
+////////////////////////////////////////////////////////////////////////////////
+OMX_ERRORTYPE EVT_CB(OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_PTR pAppData,
+ OMX_IN OMX_EVENTTYPE eEvent,
+ OMX_IN OMX_U32 nData1,
+ OMX_IN OMX_U32 nData2,
+ OMX_IN OMX_PTR pEventData)
+{
+#define SET_STATE(eState) \
+ case eState: \
+ { \
+ D("" # eState " complete"); \
+ m_eState = eState; \
+ break; \
+ }
+
+ if (eEvent == OMX_EventCmdComplete)
+ {
+ if ((OMX_COMMANDTYPE) nData1 == OMX_CommandStateSet)
+ {
+ switch ((OMX_STATETYPE) nData2)
+ {
+ SET_STATE(OMX_StateLoaded);
+ SET_STATE(OMX_StateIdle);
+ SET_STATE(OMX_StateExecuting);
+ SET_STATE(OMX_StateInvalid);
+ SET_STATE(OMX_StateWaitForResources);
+ SET_STATE(OMX_StatePause);
+ default:
+ E("invalid state %d", (int) nData2);
+ }
+ }
+ }
+
+ else if (eEvent == OMX_EventError)
+ {
+ E("OMX_EventError");
+ }
+
+ else
+ {
+ E("unexpected event %d", (int) eEvent);
+ }
+ return OMX_ErrorNone;
+}
+////////////////////////////////////////////////////////////////////////////////
+OMX_ERRORTYPE EBD_CB(OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_PTR pAppData,
+ OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+ D("Got EBD callback ts=%lld", pBuffer->nTimeStamp);
+
+ for (int i = 0; i < num_in_buffers; i++)
+ {
+ // mark this buffer ready for use again
+ if (m_pInBuffers[i] == pBuffer)
+ {
+
+ D("Marked input buffer idx %d as free, buf %p", i, pBuffer->pBuffer);
+ m_bInFrameFree[i] = OMX_TRUE;
+ break;
+ }
+ }
+
+ if (m_eMode == MODE_LIVE_ENCODE)
+ {
+ CameraTest_ReleaseFrame(pBuffer->pBuffer,
+ ((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)pBuffer->pAppPrivate));
+ }
+ else
+ {
+ // wake up main thread and tell it to send next frame
+ MsgData data;
+ data.sBitstreamData.pBuffer = pBuffer;
+ SendMessage(MSG_ID_INPUT_FRAME_DONE,
+ &data);
+
+ }
+ return OMX_ErrorNone;
+}
+////////////////////////////////////////////////////////////////////////////////
+OMX_ERRORTYPE FBD_CB(OMX_OUT OMX_HANDLETYPE hComponent,
+ OMX_OUT OMX_PTR pAppData,
+ OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
+{
+ D("Got FBD callback ts=%lld", pBuffer->nTimeStamp);
+
+ static long long prevTime = 0;
+ long long currTime = GetTimeStamp();
+
+ m_bWatchDogKicked = true;
+
+ /* Empty Buffers should not be counted */
+ if(pBuffer->nFilledLen !=0)
+ {
+ /* Counting Buffers supplied from OpneMax Encoder */
+ fbd_cnt++;
+ tot_bufsize += pBuffer->nFilledLen;
+ }
+ if (prevTime != 0)
+ {
+ long long currTime = GetTimeStamp();
+ D("FBD_DELTA = %lld\n", currTime - prevTime);
+ }
+ prevTime = currTime;
+
+ if (m_eMode == MODE_PROFILE)
+ {
+ // if we are profiling we are not doing file I/O
+ // so just give back to encoder
+ if (OMX_FillThisBuffer(m_hHandle, pBuffer) != OMX_ErrorNone)
+ {
+ E("empty buffer failed for profiling");
+ }
+ }
+ else
+ {
+ // wake up main thread and tell it to write to file
+ MsgData data;
+ data.sBitstreamData.pBuffer = pBuffer;
+ SendMessage(MSG_ID_OUTPUT_FRAME_DONE,
+ &data);
+ }
+ return OMX_ErrorNone;
+}
+////////////////////////////////////////////////////////////////////////////////
+OMX_ERRORTYPE VencTest_Initialize()
+{
+ OMX_ERRORTYPE result = OMX_ErrorNone;
+ static OMX_CALLBACKTYPE sCallbacks = {EVT_CB, EBD_CB, FBD_CB};
+ int i;
+
+ for (i = 0; i < num_in_buffers; i++)
+ {
+ m_pInBuffers[i] = NULL;
+ }
+
+ result = OMX_Init();
+ CHK(result);
+
+ if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
+ {
+ result = OMX_GetHandle(&m_hHandle,
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL,
+ &sCallbacks);
+ // CHK(result);
+ }
+ else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
+ {
+ result = OMX_GetHandle(&m_hHandle,
+ "OMX.qcom.video.encoder.h263",
+ NULL,
+ &sCallbacks);
+ CHK(result);
+ }
+ else
+ {
+ result = OMX_GetHandle(&m_hHandle,
+ "OMX.qcom.video.encoder.avc",
+ NULL,
+ &sCallbacks);
+ CHK(result);
+ }
+
+
+ result = ConfigureEncoder();
+ CHK(result);
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+OMX_ERRORTYPE VencTest_RegisterYUVBuffer(OMX_BUFFERHEADERTYPE** ppBufferHeader,
+ OMX_U8 *pBuffer,
+ OMX_PTR pAppPrivate)
+{
+ OMX_ERRORTYPE result = OMX_ErrorNone;
+#if 0
+ D("register buffer");
+ if ((result = OMX_AllocateBuffer(m_hHandle,
+ ppBufferHeader,
+ (OMX_U32) PORT_INDEX_IN,
+ pAppPrivate,
+ m_sProfile.nFrameBytes
+ )) != OMX_ErrorNone)
+ {
+ E("use buffer failed");
+ }
+ else
+ {
+ E("Allocate Buffer Success %x", (*ppBufferHeader)->pBuffer);
+ }
+ #endif
+ D("register buffer");
+ D("Calling UseBuffer for Input port");
+ if ((result = OMX_UseBuffer(m_hHandle,
+ ppBufferHeader,
+ (OMX_U32) PORT_INDEX_IN,
+ pAppPrivate,
+ m_sProfile.nFrameBytes,
+ pBuffer)) != OMX_ErrorNone)
+ {
+ E("use buffer failed");
+ }
+
+ return result;
+}
+////////////////////////////////////////////////////////////////////////////////
+OMX_ERRORTYPE VencTest_EncodeFrame(void* pYUVBuff,
+ long long nTimeStamp)
+{
+ OMX_ERRORTYPE result = OMX_ErrorUndefined;
+ D("calling OMX empty this buffer");
+ for (int i = 0; i < num_in_buffers; i++)
+ {
+ if (pYUVBuff == m_pInBuffers[i]->pBuffer)
+ {
+ m_pInBuffers[i]->nTimeStamp = nTimeStamp;
+ D("Sending Buffer - %x", m_pInBuffers[i]->pBuffer);
+ result = OMX_EmptyThisBuffer(m_hHandle,
+ m_pInBuffers[i]);
+ /* Counting Buffers supplied to OpenMax Encoder */
+ if(OMX_ErrorNone == result)
+ ebd_cnt++;
+ CHK(result);
+ break;
+ }
+ }
+ return result;
+}
+////////////////////////////////////////////////////////////////////////////////
+OMX_ERRORTYPE VencTest_Exit(void)
+{
+ int i;
+ OMX_ERRORTYPE result = OMX_ErrorNone;
+ D("trying to exit venc");
+
+ D("going to idle state");
+ SetState(OMX_StateIdle);
+
+
+ D("going to loaded state");
+ //SetState(OMX_StateLoaded);
+ OMX_SendCommand(m_hHandle,
+ OMX_CommandStateSet,
+ (OMX_U32) OMX_StateLoaded,
+ NULL);
+
+ for (i = 0; i < num_in_buffers; i++)
+ {
+ D("free buffer");
+ if (m_pInBuffers[i]->pBuffer)
+ {
+ // free(m_pInBuffers[i]->pBuffer);
+ result = OMX_FreeBuffer(m_hHandle,
+ PORT_INDEX_IN,
+ m_pInBuffers[i]);
+ CHK(result);
+ }
+ else
+ {
+ E("buffer %d is null", i);
+ result = OMX_ErrorUndefined;
+ CHK(result);
+ }
+ }
+ for (i = 0; i < num_out_buffers; i++)
+ {
+ D("free buffer");
+ if (m_pOutBuffers[i]->pBuffer)
+ {
+ free(m_pOutBuffers[i]->pBuffer);
+ result = OMX_FreeBuffer(m_hHandle,
+ PORT_INDEX_OUT,
+ m_pOutBuffers[i]);
+ CHK(result);
+
+ }
+ else
+ {
+ E("buffer %d is null", i);
+ result = OMX_ErrorUndefined;
+ CHK(result);
+ }
+ }
+
+ while (m_eState != OMX_StateLoaded)
+ {
+ sleep(1);
+ }
+ D("component_deinit...");
+ result = OMX_Deinit();
+ CHK(result);
+
+ D("venc is exiting...");
+ return result;
+}
+////////////////////////////////////////////////////////////////////////////////
+
+void VencTest_ReadDynamicConfigMsg()
+{
+ char frame_n[8], config[16], param[8];
+ char *dest = frame_n;
+ bool end = false;
+ int cntr, nparam = 0;
+ memset(&dynamic_config, 0, sizeof(struct DynamicConfig));
+ do
+ {
+ cntr = -1;
+ do
+ {
+ dest[++cntr] = fgetc(m_pDynConfFile);
+ } while(dest[cntr] != ' ' && dest[cntr] != '\t' && dest[cntr] != '\n' && dest[cntr] != '\r' && !feof(m_pDynConfFile));
+ if (dest[cntr] == '\n' || dest[cntr] == '\r')
+ end = true;
+ dest[cntr] = NULL;
+ if (dest == frame_n)
+ dest = config;
+ else if (dest == config)
+ dest = param;
+ else
+ end = true;
+ nparam++;
+ } while (!end && !feof(m_pDynConfFile));
+
+ if (nparam > 1)
+ {
+ dynamic_config.pending = true;
+ dynamic_config.frame_num = atoi(frame_n);
+ if (!strcmp(config, "bitrate"))
+ {
+ dynamic_config.config_param = OMX_IndexConfigVideoBitrate;
+ dynamic_config.config_data.bitrate.nPortIndex = PORT_INDEX_OUT;
+ dynamic_config.config_data.bitrate.nEncodeBitrate = strtoul(param, NULL, 10);
+ }
+ else if (!strcmp(config, "framerate"))
+ {
+ dynamic_config.config_param = OMX_IndexConfigVideoFramerate;
+ dynamic_config.config_data.framerate.nPortIndex = PORT_INDEX_OUT;
+ dynamic_config.config_data.f_framerate = atof(param);
+ }
+ else if (!strcmp(config, "iperiod"))
+ {
+ dynamic_config.config_param = (OMX_INDEXTYPE)QOMX_IndexConfigVideoIntraperiod;
+ dynamic_config.config_data.intraperiod.nPortIndex = PORT_INDEX_OUT;
+ dynamic_config.config_data.intraperiod.nPFrames = strtoul(param, NULL, 10) - 1;
+ dynamic_config.config_data.intraperiod.nIDRPeriod = 1; // This value is ignored in OMX component
+ }
+ else if (!strcmp(config, "ivoprefresh"))
+ {
+ dynamic_config.config_param = OMX_IndexConfigVideoIntraVOPRefresh;
+ dynamic_config.config_data.intravoprefresh.nPortIndex = PORT_INDEX_OUT;
+ dynamic_config.config_data.intravoprefresh.IntraRefreshVOP = OMX_TRUE;
+ }
+ else if (!strcmp(config, "rotation"))
+ {
+ dynamic_config.config_param = OMX_IndexConfigCommonRotate;
+ dynamic_config.config_data.rotation.nPortIndex = PORT_INDEX_OUT;
+ dynamic_config.config_data.rotation.nRotation = strtoul(param, NULL, 10);
+ }
+ else
+ {
+ E("UNKNOWN CONFIG PARAMETER: %s!", config);
+ dynamic_config.pending = false;
+ }
+ }
+ else if (feof(m_pDynConfFile))
+ {
+ fclose(m_pDynConfFile);
+ m_pDynConfFile = NULL;
+ }
+}
+
+void VencTest_ProcessDynamicConfigurationFile()
+{
+ do
+ {
+ if (dynamic_config.pending)
+ {
+ if(m_nFrameIn == dynamic_config.frame_num)
+ {
+ if (dynamic_config.config_param == OMX_IndexConfigVideoFramerate)
+ {
+ m_sProfile.nFramerate = dynamic_config.config_data.f_framerate;
+ FractionToQ16(dynamic_config.config_data.framerate.xEncodeFramerate,
+ (int)(m_sProfile.nFramerate * 2), 2);
+ }
+ if (OMX_SetConfig(m_hHandle, dynamic_config.config_param,
+ &dynamic_config.config_data) != OMX_ErrorNone)
+ E("ERROR: Setting dynamic config to OMX param[0x%x]", dynamic_config.config_param);
+ dynamic_config.pending = false;
+ }
+ else if (m_nFrameIn > dynamic_config.frame_num)
+ {
+ E("WARNING: Config change requested in passed frame(%d)", dynamic_config.frame_num);
+ dynamic_config.pending = false;
+ }
+ }
+ if (!dynamic_config.pending)
+ VencTest_ReadDynamicConfigMsg();
+ } while (!dynamic_config.pending && m_pDynConfFile);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+OMX_ERRORTYPE VencTest_ReadAndEmpty(OMX_BUFFERHEADERTYPE* pYUVBuffer)
+{
+ OMX_ERRORTYPE result = OMX_ErrorNone;
+#ifdef T_ARM
+#ifdef MAX_RES_720P
+ if (read(m_nInFd,
+ pYUVBuffer->pBuffer,
+ m_sProfile.nFrameBytes) != m_sProfile.nFrameBytes)
+ {
+ return OMX_ErrorUndefined;
+ }
+#elif BADGER
+ int bytes;
+ E("will read YUV now: %d bytes to buffer %p\n", m_sProfile.nFrameRead, pYUVBuffer->pBuffer);
+ E("W: %d H: %d Str: %d scal: %d \n", m_sProfile.nFrameWidth, m_sProfile.nFrameHeight,
+ m_sProfile.nFramestride, m_sProfile.nFrameScanlines);
+ bytes = read(m_nInFd, pYUVBuffer->pBuffer, m_sProfile.nFrameRead);
+ if (bytes != m_sProfile.nFrameRead) {
+ E("read failed: %d != %d\n", read, m_sProfile.nFrameRead);
+ return OMX_ErrorUndefined;
+ }
+ E("\n\nRead %d bytes\n\n\n", m_sProfile.nFrameRead);
+#else
+ OMX_U32 bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight;
+ // read Y first
+ if (read(m_nInFd,
+ pYUVBuffer->pBuffer,
+ bytestoread) != bytestoread)
+ return OMX_ErrorUndefined;
+
+ // check alignment for offset to C
+ OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight;
+
+ const OMX_U32 C_2K = (1024*2),
+ MASK_2K = C_2K-1,
+ IMASK_2K = ~MASK_2K;
+
+ if (offset_to_c & MASK_2K)
+ {
+ // offset to C is not 2k aligned, adjustment is required
+ offset_to_c = (offset_to_c & IMASK_2K) + C_2K;
+ }
+
+ bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2;
+ // read C
+ if (read(m_nInFd,
+ pYUVBuffer->pBuffer + offset_to_c,
+ bytestoread)!= bytestoread)
+ return OMX_ErrorUndefined;
+#endif
+#else
+ {
+ char * pInputbuf = (char *)(pYUVBuffer->pBuffer) ;
+ read(m_nInFd,pInputbuf,m_sProfile.nFrameBytes) ;
+
+ }
+#endif
+ if (m_pDynConfFile)
+ VencTest_ProcessDynamicConfigurationFile();
+ D("about to call VencTest_EncodeFrame...");
+ pthread_mutex_lock(&m_mutex);
+ ++m_nFrameIn;
+#ifdef BADGER
+ pYUVBuffer->nFilledLen = m_sProfile.nFrameRead;
+#else
+ pYUVBuffer->nFilledLen = m_sProfile.nFrameBytes;
+#endif
+ D("Called Buffer with Data filled length %d",pYUVBuffer->nFilledLen);
+
+ result = VencTest_EncodeFrame(pYUVBuffer->pBuffer,
+ m_nTimeStamp);
+
+ m_nTimeStamp += (1000000) / m_sProfile.nFramerate;
+ CHK(result);
+ pthread_mutex_unlock(&m_mutex);
+ return result;
+}
+////////////////////////////////////////////////////////////////////////////////
+void PreviewCallback(int nFD,
+ int nOffset,
+ void* pPhys,
+ void* pVirt,
+ long long nTimeStamp)
+{
+
+ D("================= preview frame %d, phys=0x%x, nTimeStamp(millis)=%lld",
+ m_nFrameIn+1, pPhys, (nTimeStamp / 1000));
+
+ if (m_nFrameIn == m_nFramePlay &&
+ m_nFramePlay != 0)
+ {
+ // we will stop camera after last frame is encoded.
+ // for now just ignore input frames
+
+ CameraTest_ReleaseFrame(pPhys, pVirt);
+ return;
+ }
+
+ // see if we should stop
+ pthread_mutex_lock(&m_mutex);
+ ++m_nFrameIn;
+ pthread_mutex_unlock(&m_mutex);
+
+
+ if (m_eMode == MODE_LIVE_ENCODE)
+ {
+
+ OMX_ERRORTYPE result;
+
+ // register new camera buffers with encoder
+ int i;
+ for (i = 0; i < num_in_buffers; i++)
+ {
+ if (m_pInBuffers[i] != NULL &&
+ m_pInBuffers[i]->pBuffer == pPhys)
+ {
+ break;
+ }
+ else if (m_pInBuffers[i] == NULL)
+ {
+ D("registering buffer...");
+ result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i],
+ (OMX_U8*) pPhys,
+ (OMX_PTR) pVirt); // store virt in app private field
+ D("register done");
+ CHK(result);
+ break;
+ }
+ }
+
+ if (i == num_in_buffers)
+ {
+ E("There are more camera buffers than we thought");
+ CHK(1);
+ }
+
+ // encode the yuv frame
+
+ D("StartEncodeTime=%lld", GetTimeStamp());
+ result = VencTest_EncodeFrame(pPhys,
+ nTimeStamp);
+ CHK(result);
+ // FBTest_DisplayImage(nFD, nOffset);
+ }
+ else
+ {
+ // FBTest_DisplayImage(nFD, nOffset);
+ CameraTest_ReleaseFrame(pPhys, pVirt);
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void usage(char* filename)
+{
+ char* fname = strrchr(filename, (int) '/');
+ fname = (fname == NULL) ? filename : fname;
+
+ fprintf(stderr, "usage: %s LIVE <QCIF|QVGA> <MP4|H263> <FPS> <BITRATE> <NFRAMES> <OUTFILE>\n", fname);
+ fprintf(stderr, "usage: %s FILE <QCIF|QVGA> <MP4|H263 <FPS> <BITRATE> <NFRAMES> <INFILE> <OUTFILE> ", fname);
+ fprintf(stderr, "<Dynamic config file - opt> <Rate Control - opt> <AVC Slice Mode - opt>\n", fname);
+ fprintf(stderr, "usage: %s PROFILE <QCIF|QVGA> <MP4|H263 <FPS> <BITRATE> <NFRAMES> <INFILE>\n", fname);
+ fprintf(stderr, "usage: %s PREVIEW <QCIF|QVGA> <FPS> <NFRAMES>\n", fname);
+ fprintf(stderr, "usage: %s DISPLAY <QCIF|QVGA> <FPS> <NFRAMES> <INFILE>\n", fname);
+ fprintf(stderr, "\n BITRATE - bitrate in kbps\n");
+ fprintf(stderr, " FPS - frames per second\n");
+ fprintf(stderr, " NFRAMES - number of frames to play, 0 for infinite\n");
+ fprintf(stderr, " RateControl (Values 0 - 4 for RC_OFF, RC_CBR_CFR, RC_CBR_VFR, RC_VBR_CFR, RC_VBR_VFR\n");
+ exit(1);
+}
+
+bool parseWxH(char *str, OMX_U32 *width, OMX_U32 *height)
+{
+ bool parseOK = false;
+ const char delimiters[] = " x*,";
+ char *token, *dupstr, *temp;
+ OMX_U32 w, h;
+
+ dupstr = strdup(str);
+ token = strtok_r(dupstr, delimiters, &temp);
+ if (token)
+ {
+ w = strtoul(token, NULL, 10);
+ token = strtok_r(NULL, delimiters, &temp);
+ if (token)
+ {
+ h = strtoul(token, NULL, 10);
+ if (w != ULONG_MAX && h != ULONG_MAX)
+ {
+#ifdef MAX_RES_720P
+ if ((w * h >> 8) <= 3600)
+ {
+ parseOK = true;
+ *width = w;
+ *height = h;
+ }
+#else
+ if ((w * h >> 8) <= 8160)
+ {
+ parseOK = true;
+ *width = w;
+ *height = h;
+ }
+#endif
+ else
+ E("\nInvalid dimensions %dx%d",w,h);
+ }
+ }
+ }
+ free(dupstr);
+ return parseOK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void parseArgs(int argc, char** argv)
+{
+ int dyn_file_arg = argc;
+ if (argc == 1)
+ {
+ usage(argv[0]);
+ }
+ else if (strcmp("PREVIEW", argv[1]) == 0 ||
+ strcmp("preview", argv[1]) == 0)
+ {
+ m_eMode = MODE_PREVIEW;
+ if (argc != 5)
+ {
+ usage(argv[0]);
+ }
+ }
+ else if (strcmp("DISPLAY", argv[1]) == 0 ||
+ strcmp("display", argv[1]) == 0)
+ {
+ m_eMode = MODE_DISPLAY;
+ if (argc != 6)
+ {
+ usage(argv[0]);
+ }
+ m_sProfile.cInFileName = argv[5];
+ m_sProfile.cOutFileName = NULL;
+ }
+ else if (strcmp("LIVE", argv[1]) == 0 ||
+ strcmp("live", argv[1]) == 0)
+ {//263
+ m_eMode = MODE_LIVE_ENCODE;
+ if (argc != 8)
+ {
+ usage(argv[0]);
+ }
+ m_sProfile.cInFileName = NULL;
+ m_sProfile.cOutFileName = argv[7];
+ }
+ else if (strcmp("FILE", argv[1]) == 0 ||
+ strcmp("file", argv[1]) == 0)
+ {//263
+ m_eMode = MODE_FILE_ENCODE;
+
+ if(argc < 9 || argc > 13)
+ {
+ usage(argv[0]);
+ }
+ else
+ {
+ if (argc > 9)
+ dyn_file_arg = 9;
+
+ if (argc > 10)
+ {
+ m_sProfile.eControlRate = OMX_Video_ControlRateVariable;
+ int RC = atoi(argv[10]);
+
+ switch (RC)
+ {
+ case 0:
+ m_sProfile.eControlRate = OMX_Video_ControlRateDisable ;//VENC_RC_NONE
+ break;
+ case 1:
+ m_sProfile.eControlRate = OMX_Video_ControlRateConstant;//VENC_RC_CBR_CFR
+ break;
+
+ case 2:
+ m_sProfile.eControlRate = OMX_Video_ControlRateConstantSkipFrames;//VENC_RC_CBR_VFR
+ break;
+
+ case 3:
+ m_sProfile.eControlRate =OMX_Video_ControlRateVariable ;//VENC_RC_VBR_CFR
+ break;
+
+ case 4:
+ m_sProfile.eControlRate = OMX_Video_ControlRateVariableSkipFrames;//VENC_RC_VBR_VFR
+ break;
+
+ default:
+ E("invalid rate control selection");
+ m_sProfile.eControlRate = OMX_Video_ControlRateVariable; //VENC_RC_VBR_CFR
+ break;
+ }
+ }
+
+ if (argc > 11)
+ {
+ int profile_argi = 11;
+ if(!strcmp(argv[3], "H264") || !strcmp(argv[3], "h264"))
+ {
+ profile_argi = 12;
+ D("\nSetting AVCSliceMode ... ");
+ int AVCSliceMode = atoi(argv[11]);
+ switch(AVCSliceMode)
+ {
+ case 0:
+ m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
+ break;
+
+ case 1:
+ m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCMBSlice;
+ break;
+
+ case 2:
+ m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCByteSlice;
+ break;
+
+ default:
+ E("invalid Slice Mode");
+ m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
+ break;
+ }
+ }
+ if (profile_argi < argc)
+ {
+ if (!strncmp(argv[profile_argi], "0x", 2) || !strncmp(argv[profile_argi], "0x", 2))
+ {
+ m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 16);
+ }
+ else
+ {
+ m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 10);
+ }
+ if (!m_sProfile.nUserProfile || m_sProfile.nUserProfile == ULONG_MAX)
+ {
+ E("invalid specified Profile %s, using default", argv[profile_argi]);
+ m_sProfile.nUserProfile = 0;
+ }
+ }
+ }
+ }
+ m_sProfile.cInFileName = argv[7];
+ m_sProfile.cOutFileName = argv[8];
+ }
+ else if (strcmp("PROFILE", argv[1]) == 0 ||
+ strcmp("profile", argv[1]) == 0)
+ {//263
+ m_eMode = MODE_PROFILE;
+ if (argc != 8)
+ {
+ usage(argv[0]);
+ }
+ m_sProfile.cInFileName = argv[7];
+ m_sProfile.cOutFileName = NULL;
+ }
+ else
+ {
+ usage(argv[0]);
+ }
+
+
+ if (strcmp("QCIF", argv[2]) == 0 ||
+ strcmp("qcif", argv[2]) == 0)
+ {
+ m_sProfile.nFrameWidth = 176;
+ m_sProfile.nFrameHeight = 144;
+ m_sProfile.nFrameBytes = 176*144*3/2;
+ m_sProfile.eLevel = OMX_VIDEO_MPEG4Level0;
+ }
+ else if (strcmp("QVGA", argv[2]) == 0 ||
+ strcmp("qvga", argv[2]) == 0)
+ {
+ m_sProfile.nFrameWidth = 320;
+ m_sProfile.nFrameHeight = 240;
+ m_sProfile.nFrameBytes = 320*240*3/2;
+ m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
+ }
+
+
+ else if (strcmp("VGA", argv[2]) == 0 ||
+ strcmp("vga", argv[2]) == 0)
+ {
+ m_sProfile.nFrameWidth = 640;
+ m_sProfile.nFrameHeight = 480;
+ m_sProfile.nFrameBytes = 640*480*3/2;
+ m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
+ }
+
+ else if (strcmp("WVGA", argv[2]) == 0 ||
+ strcmp("wvga", argv[2]) == 0)
+ {
+ m_sProfile.nFrameWidth = 800;
+ m_sProfile.nFrameHeight = 480;
+ m_sProfile.nFrameBytes = 800*480*3/2;
+ m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
+ }
+ else if (strcmp("CIF", argv[2]) == 0 ||
+ strcmp("cif", argv[2]) == 0)
+ {
+ m_sProfile.nFrameWidth = 352;
+ m_sProfile.nFrameHeight = 288;
+ m_sProfile.nFrameBytes = 352*288*3/2;
+ m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
+ }
+ else if (strcmp("720", argv[2]) == 0)
+ {
+ m_sProfile.nFrameWidth = 1280;
+ m_sProfile.nFrameHeight = 720;
+ m_sProfile.nFrameBytes = 720*1280*3/2;
+ m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
+ }
+ else if (strcmp("1080", argv[2]) == 0)
+ {
+ m_sProfile.nFrameWidth = 1920;
+ m_sProfile.nFrameHeight = 1080;
+ m_sProfile.nFrameBytes = 1920*1080*3/2;
+ m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
+ }
+ else if (parseWxH(argv[2], &m_sProfile.nFrameWidth, &m_sProfile.nFrameHeight))
+ {
+ m_sProfile.nFrameBytes = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight*3/2;
+ m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
+ }
+ else
+ {
+ usage(argv[0]);
+ }
+
+#ifdef BADGER
+ m_sProfile.nFramestride = (m_sProfile.nFrameWidth + 31) & (~31);
+ m_sProfile.nFrameScanlines = (m_sProfile.nFrameHeight + 31) & (~31);
+ m_sProfile.nFrameBytes = ((m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2) + 4095) & (~4095);
+ E("stride: %d, Scanlines: %d, Size: %d",
+ m_sProfile.nFramestride, m_sProfile.nFrameScanlines, m_sProfile.nFrameBytes);
+ m_sProfile.nFrameRead = m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2;
+#endif
+ if (m_eMode == MODE_DISPLAY ||
+ m_eMode == MODE_PREVIEW)
+ {
+ m_sProfile.nFramerate = atof(argv[3]);
+ m_nFramePlay = atoi(argv[4]);
+
+ }
+ else if (m_eMode == MODE_LIVE_ENCODE ||
+ m_eMode == MODE_FILE_ENCODE ||
+ m_eMode == MODE_PROFILE)
+ {
+ if ((!strcmp(argv[3], "MP4")) || (!strcmp(argv[3], "mp4")))
+ {
+ m_sProfile.eCodec = OMX_VIDEO_CodingMPEG4;
+ }
+ else if ((!strcmp(argv[3], "H263")) || (!strcmp(argv[3], "h263")))
+ {
+ m_sProfile.eCodec = OMX_VIDEO_CodingH263;
+ }
+ else if ((!strcmp(argv[3], "H264")) || (!strcmp(argv[3], "h264")))
+ {
+ m_sProfile.eCodec = OMX_VIDEO_CodingAVC;
+ }
+ else
+ {
+ usage(argv[0]);
+ }
+
+ m_sProfile.nFramerate = atof(argv[4]);
+ m_sProfile.nBitrate = atoi(argv[5]);
+// m_sProfile.eControlRate = OMX_Video_ControlRateVariable;
+ m_nFramePlay = atoi(argv[6]);
+ if (dyn_file_arg < argc)
+ {
+ m_pDynConfFile = fopen(argv[dyn_file_arg], "r");
+ if (!m_pDynConfFile)
+ E("ERROR: Cannot open dynamic config file: %s", argv[dyn_file_arg]);
+ else
+ {
+ memset(&dynamic_config, 0, sizeof(struct DynamicConfig));
+ }
+ }
+ }
+}
+
+void* Watchdog(void* data)
+{
+ while (1)
+ {
+ sleep(1000);
+ if (m_bWatchDogKicked == true)
+ m_bWatchDogKicked = false;
+ else
+ E("watchdog has not been kicked. we may have a deadlock");
+ }
+ return NULL;
+}
+
+int main(int argc, char** argv)
+{
+ OMX_U8* pvirt = NULL;
+ int result;
+ float enc_time_sec=0.0,enc_time_usec=0.0;
+
+ m_nInFd = -1;
+ m_nOutFd = -1;
+ m_nTimeStamp = 0;
+ m_nFrameIn = 0;
+ m_nFrameOut = 0;
+
+ memset(&m_sMsgQ, 0, sizeof(MsgQ));
+ parseArgs(argc, argv);
+
+ D("fps=%d, bitrate=%d, width=%d, height=%d",
+ m_sProfile.nFramerate,
+ m_sProfile.nBitrate,
+ m_sProfile.nFrameWidth,
+ m_sProfile.nFrameHeight);
+
+
+ //if (m_eMode != MODE_PREVIEW && m_eMode != MODE_DISPLAY)
+ //{
+ // pthread_t wd;
+ // pthread_create(&wd, NULL, Watchdog, NULL);
+ //}
+
+ for (int x = 0; x < num_in_buffers; x++)
+ {
+ // mark all buffers as ready to use
+ m_bInFrameFree[x] = OMX_TRUE;
+ }
+
+
+ if (m_eMode != MODE_PROFILE)
+ {
+ #if T_ARM
+ m_nOutFd = open(m_sProfile.cOutFileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
+ #else
+ m_nOutFd = open(m_sProfile.cOutFileName,0);
+ #endif
+ if (m_nOutFd < 0)
+ {
+ E("could not open output file %s", m_sProfile.cOutFileName);
+ CHK(1);
+ }
+ }
+
+ pthread_mutex_init(&m_mutex, NULL);
+ pthread_cond_init(&m_signal, NULL);
+
+ if (m_eMode != MODE_PREVIEW)
+ {
+ VencTest_Initialize();
+ }
+
+ ////////////////////////////////////////
+ // Camera + Encode
+ ////////////////////////////////////////
+ if (m_eMode == MODE_LIVE_ENCODE)
+ {
+ CameraTest_Initialize(m_sProfile.nFramerate,
+ m_sProfile.nFrameWidth,
+ m_sProfile.nFrameHeight,
+ PreviewCallback);
+ CameraTest_Run();
+ }
+
+ if (m_eMode == MODE_FILE_ENCODE ||
+ m_eMode == MODE_PROFILE)
+ {
+ int i;
+ #if T_ARM
+ m_nInFd = open(m_sProfile.cInFileName, O_RDONLY);
+ #else
+ m_nInFd = open(m_sProfile.cInFileName,1);
+ #endif
+ if (m_nInFd < 0)
+ {
+ E("could not open input file");
+ CHK(1);
+
+ }
+ D("going to idle state");
+ //SetState(OMX_StateIdle);
+ OMX_SendCommand(m_hHandle,
+ OMX_CommandStateSet,
+ (OMX_U32) OMX_StateIdle,
+ NULL);
+
+ OMX_PARAM_PORTDEFINITIONTYPE portDef;
+
+ portDef.nPortIndex = 0;
+ result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef);
+ CHK(result);
+
+ D("allocating Input buffers");
+ num_in_buffers = portDef.nBufferCountActual;
+ for (i = 0; i < portDef.nBufferCountActual; i++)
+ {
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem = new OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO;
+ pvirt = (OMX_U8*)PmemMalloc(pMem, m_sProfile.nFrameBytes);
+
+ if(pvirt == NULL)
+ {
+ CHK(1);
+ }
+ result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i],
+ (OMX_U8*) pvirt,
+ (OMX_PTR) pMem);
+ CHK(result);
+ }
+ }
+ else if (m_eMode == MODE_LIVE_ENCODE)
+ {
+ D("going to idle state");
+ //SetState(OMX_StateIdle);
+ OMX_SendCommand(m_hHandle,
+ OMX_CommandStateSet,
+ (OMX_U32) OMX_StateIdle,
+ NULL);
+ }
+
+ int i;
+ OMX_PARAM_PORTDEFINITIONTYPE portDef;
+
+ portDef.nPortIndex = 1;
+ result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef);
+ CHK(result);
+
+ D("allocating output buffers");
+ D("Calling UseBuffer for Output port");
+ num_out_buffers = portDef.nBufferCountActual;
+ for (i = 0; i < portDef.nBufferCountActual; i++)
+ {
+ void* pBuff;
+
+ pBuff = malloc(portDef.nBufferSize);
+ D("portDef.nBufferSize = %d ",portDef.nBufferSize);
+ result = OMX_UseBuffer(m_hHandle,
+ &m_pOutBuffers[i],
+ (OMX_U32) PORT_INDEX_OUT,
+ NULL,
+ portDef.nBufferSize,
+ (OMX_U8*) pBuff);
+ CHK(result);
+ }
+ D("allocate done");
+
+ // D("Going to state " # eState"...");
+
+ while (m_eState != OMX_StateIdle)
+ {
+ sleep(1);
+ }
+ //D("Now in state " # eState);
+
+
+ D("going to executing state");
+ SetState(OMX_StateExecuting);
+ for (i = 0; i < num_out_buffers; i++)
+ {
+ D("filling buffer %d", i);
+ result = OMX_FillThisBuffer(m_hHandle, m_pOutBuffers[i]);
+ //sleep(1000);
+ CHK(result);
+ }
+
+ if (m_eMode == MODE_FILE_ENCODE)
+ {
+ // encode the first frame to kick off the whole process
+ VencTest_ReadAndEmpty(m_pInBuffers[0]);
+ // FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[0]->pAppPrivate)->fd,0);
+ }
+
+ if (m_eMode == MODE_PROFILE)
+ {
+ int i;
+
+ // read several frames into memory
+ D("reading frames into memory");
+ for (i = 0; i < num_in_buffers; i++)
+ {
+ D("[%d] address 0x%x",i, m_pInBuffers[i]->pBuffer);
+#ifdef MAX_RES_720P
+ read(m_nInFd,
+ m_pInBuffers[i]->pBuffer,
+ m_sProfile.nFrameBytes);
+#else
+ // read Y first
+ read(m_nInFd,
+ m_pInBuffers[i]->pBuffer,
+ m_sProfile.nFrameWidth*m_sProfile.nFrameHeight);
+
+ // check alignment for offset to C
+ OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight;
+
+ const OMX_U32 C_2K = (1024*2),
+ MASK_2K = C_2K-1,
+ IMASK_2K = ~MASK_2K;
+
+ if (offset_to_c & MASK_2K)
+ {
+ // offset to C is not 2k aligned, adjustment is required
+ offset_to_c = (offset_to_c & IMASK_2K) + C_2K;
+ }
+
+ // read C
+ read(m_nInFd,
+ m_pInBuffers[i]->pBuffer + offset_to_c,
+ m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2);
+#endif
+
+ }
+
+ // FBTest_Initialize(m_sProfile.nFrameWidth, m_sProfile.nFrameHeight);
+
+ // loop over the mem-resident frames and encode them
+ D("beging playing mem-resident frames...");
+ for (i = 0; m_nFramePlay == 0 || i < m_nFramePlay; i++)
+ {
+ int idx = i % num_in_buffers;
+ if (m_bInFrameFree[idx] == OMX_FALSE)
+ {
+ int j;
+ E("the expected buffer is not free, but lets find another");
+
+ idx = -1;
+
+ // lets see if we can find another free buffer
+ for (j = 0; j < num_in_buffers; j++)
+ {
+ if(m_bInFrameFree[j])
+ {
+ idx = j;
+ break;
+ }
+ }
+ }
+
+ // if we have a free buffer let's encode it
+ if (idx >= 0)
+ {
+ D("encode frame %d...m_pInBuffers[idx]->pBuffer=0x%x", i,m_pInBuffers[idx]->pBuffer);
+ m_bInFrameFree[idx] = OMX_FALSE;
+ VencTest_EncodeFrame(m_pInBuffers[idx]->pBuffer,
+ m_nTimeStamp);
+ D("display frame %d...", i);
+ // FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[idx]->pAppPrivate)->fd,0);
+ m_nTimeStamp += 1000000 / m_sProfile.nFramerate;
+ }
+ else
+ {
+ E("wow, no buffers are free, performance "
+ "is not so good. lets just sleep some more");
+
+ }
+ D("sleep for %d microsec", 1000000/m_sProfile.nFramerate);
+ sleep (1000000 / m_sProfile.nFramerate);
+ }
+ // FBTest_Exit();
+ }
+
+ Msg msg;
+ bool bQuit = false;
+ while ((m_eMode == MODE_FILE_ENCODE || m_eMode == MODE_LIVE_ENCODE) &&
+ !bQuit)
+ {
+ PopMessage(&msg);
+ switch (msg.id)
+ {
+ //////////////////////////////////
+ // FRAME IS ENCODED
+ //////////////////////////////////
+ case MSG_ID_INPUT_FRAME_DONE:
+ /*pthread_mutex_lock(&m_mutex);
+ ++m_nFrameOut;
+ if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0)
+ {
+ bQuit = true;
+ }
+ pthread_mutex_unlock(&m_mutex);*/
+
+ if (!bQuit && m_eMode == MODE_FILE_ENCODE)
+ {
+ D("pushing another frame down to encoder");
+ if (VencTest_ReadAndEmpty(msg.data.sBitstreamData.pBuffer))
+ {
+ // we have read the last frame
+ D("main is exiting...");
+ bQuit = true;
+ }
+ }
+ break;
+ case MSG_ID_OUTPUT_FRAME_DONE:
+ D("================ writing frame %d = %d bytes to output file",
+ m_nFrameOut+1,
+ msg.data.sBitstreamData.pBuffer->nFilledLen);
+ D("StopEncodeTime=%lld", GetTimeStamp());
+
+
+ write(m_nOutFd,
+ msg.data.sBitstreamData.pBuffer->pBuffer,
+ msg.data.sBitstreamData.pBuffer->nFilledLen);
+
+
+ result = OMX_FillThisBuffer(m_hHandle,
+ msg.data.sBitstreamData.pBuffer);
+
+ if (result != OMX_ErrorNone)
+ {
+ CHK(result);
+ }
+
+ pthread_mutex_lock(&m_mutex);
+ ++m_nFrameOut;
+ if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0)
+ {
+ bQuit = true;
+ }
+ pthread_mutex_unlock(&m_mutex);
+ break;
+
+ default:
+ E("invalid msg id %d", (int) msg.id);
+ } // end switch (msg.id)
+
+/* // TO UNCOMMENT FOR PAUSE TESTINGS
+ if(m_nFrameOut == 10)
+ {
+ E("\nGoing to Pause state\n");
+ SetState(OMX_StatePause);
+ sleep(3);
+//REQUEST AN I FRAME AFTER PAUSE
+ OMX_CONFIG_INTRAREFRESHVOPTYPE voprefresh;
+ voprefresh.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
+ voprefresh.IntraRefreshVOP = OMX_TRUE;
+ result = OMX_SetConfig(m_hHandle,
+ OMX_IndexConfigVideoIntraVOPRefresh,
+ &voprefresh);
+ E("\n OMX_IndexConfigVideoIntraVOPRefresh Set Paramter port");
+ CHK(result);
+ E("\nGoing to executing state\n");
+ SetState(OMX_StateExecuting);
+ }
+*/
+ } // end while (!bQuit)
+
+
+ if (m_eMode == MODE_LIVE_ENCODE)
+ {
+ CameraTest_Exit();
+ close(m_nOutFd);
+ }
+ else if (m_eMode == MODE_FILE_ENCODE ||
+ m_eMode == MODE_PROFILE)
+ {
+ // deallocate pmem buffers
+ for (int i = 0; i < num_in_buffers; i++)
+ {
+ PmemFree((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)m_pInBuffers[i]->pAppPrivate,
+ m_pInBuffers[i]->pBuffer,
+ m_sProfile.nFrameBytes);
+ delete (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*) m_pInBuffers[i]->pAppPrivate;
+ }
+ close(m_nInFd);
+
+ if (m_eMode == MODE_FILE_ENCODE)
+ {
+ close(m_nOutFd);
+ }
+ if (m_pDynConfFile)
+ {
+ fclose(m_pDynConfFile);
+ m_pDynConfFile = NULL;
+ }
+ }
+
+ if (m_eMode != MODE_PREVIEW)
+ {
+ D("exit encoder test");
+ VencTest_Exit();
+ }
+
+ pthread_mutex_destroy(&m_mutex);
+ pthread_cond_destroy(&m_signal);
+
+ /* Time Statistics Logging */
+ if(0 != m_sProfile.nFramerate)
+ {
+ enc_time_usec = m_nTimeStamp - (1000000 / m_sProfile.nFramerate);
+ enc_time_sec =enc_time_usec/1000000;
+ if(0 != enc_time_sec)
+ {
+ printf("Total Frame Rate: %f",ebd_cnt/enc_time_sec);
+ printf("\nEncoder Bitrate :%lf Kbps",(tot_bufsize*8)/(enc_time_sec*1000));
+ }
+ }
+ else
+ {
+ printf("\n\n Encode Time is zero");
+ }
+ printf("\nTotal Number of Frames :%d",ebd_cnt);
+ printf("\nNumber of dropped frames during encoding:%d\n",ebd_cnt-fbd_cnt);
+ /* End of Time Statistics Logging */
+
+ D("main has exited");
+ return 0;
+}
diff --git a/mm-video/vidc/venc/test/venc_util.c b/mm-video/vidc/venc/test/venc_util.c
new file mode 100755
index 0000000..1f03810
--- /dev/null
+++ b/mm-video/vidc/venc/test/venc_util.c
@@ -0,0 +1,51 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+/*============================================================================
+ V E N C _ U T I L. C
+
+DESCRIPTION
+
+
+REFERENCES
+
+============================================================================*/
+
+#include "venc_util.h"
+#include <time.h>
+#include <sys/time.h>
+
+long long GetTimeStamp()
+{
+ struct timeval tv;
+ long long microsec;
+ gettimeofday(&tv, NULL);
+ microsec = (tv.tv_sec * 1000000) + (tv.tv_usec);
+ return microsec;
+
+}
+
diff --git a/mm-video/vidc/venc/test/video_encoder_test.c b/mm-video/vidc/venc/test/video_encoder_test.c
new file mode 100755
index 0000000..0eb5f3c
--- /dev/null
+++ b/mm-video/vidc/venc/test/video_encoder_test.c
@@ -0,0 +1,1064 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+#include "video_encoder_test.h"
+
+#define DEBUG_PRINT printf
+/************************************************************************/
+/* #DEFINES */
+/************************************************************************/
+
+#define VOP_START_CODE 0x000001B6
+#define SHORT_HEADER_START_CODE 0x00008000
+#define H264_START_CODE 0x00000001
+
+/************************************************************************/
+/* STATIC VARIABLES */
+/************************************************************************/
+
+static int Code_type;
+static int total_frames = 0;
+static unsigned int header_code = 0;
+static pthread_mutex_t read_lock;
+
+static unsigned int read_frame ( unsigned char *dataptr,unsigned int length,
+ FILE * inputBufferFile
+ );
+static unsigned clp2(unsigned x)
+{
+ x = x - 1;
+ x = x | (x >> 1);
+ x = x | (x >> 2);
+ x = x | (x >> 4);
+ x = x | (x >> 8);
+ x = x | (x >>16);
+ return x + 1;
+}
+
+
+static void* video_thread (void *);
+static void* async_thread (void *);
+
+
+
+int main (int argc, char **argv)
+{
+ struct video_encoder_context *encoder_context = NULL;
+ char *file_name = NULL;
+ FILE *file_ptr = NULL;
+ int temp1 =0,temp2 =0;
+ int error = 1;
+ unsigned int i = 0;
+
+ file_name = argv [1];
+ file_ptr = fopen (file_name,"rb");
+
+ if (file_ptr == NULL)
+ {
+ DEBUG_PRINT("\n File is not located ");
+ return -1;
+ }
+
+
+ encoder_context = (struct video_encoder_context *) \
+ calloc (sizeof (struct video_encoder_context),1);
+ if (encoder_context == NULL)
+ {
+ return -1;
+ }
+ encoder_context->outputBufferFile = NULL;
+ encoder_context->inputBufferFile = NULL;
+ encoder_context->video_driver_fd = -1;
+ encoder_context->inputBufferFile = file_ptr;
+ encoder_context->input_width = 176;
+ encoder_context->input_height = 144;
+ encoder_context->codectype = VEN_CODEC_MPEG4;
+ encoder_context->fps_num = 60;
+ encoder_context->fps_den = 2;
+ encoder_context->inputformat = VEN_INPUTFMT_NV12;
+ encoder_context->targetbitrate = 128000;
+
+ file_ptr = fopen ("/data/output.m4v","wb");
+ if (file_ptr == NULL)
+ {
+ DEBUG_PRINT("\n File can't be created");
+ free (encoder_context);
+ return -1;
+ }
+ encoder_context->outputBufferFile = file_ptr;
+
+ switch (atoi(argv[2]))
+ {
+ case 0:
+ DEBUG_PRINT("\n MPEG4 codec selected");
+ encoder_context->codectype = VEN_CODEC_MPEG4;
+ Code_type = 0;
+ break;
+ case 1:
+ DEBUG_PRINT("\n H.263");
+ encoder_context->codectype = VEN_CODEC_H263;
+ Code_type = 0;
+ break;
+ case 2:
+ DEBUG_PRINT("\n H.264");
+ encoder_context->codectype = VEN_CODEC_H264;
+ Code_type = 1;
+ break;
+ default:
+ DEBUG_PRINT("\n Wrong codec type");
+ error = -1;
+ break;
+ }
+
+ if (error != -1)
+ {
+ temp1 = atoi(argv[3]);
+ temp2 = atoi(argv[4]);
+
+ if (((temp1%16) != 0) || ((temp2%16) != 0))
+ {
+ error = -1;
+ }
+ else
+ {
+ encoder_context->input_width = temp1;
+ encoder_context->input_height = temp2;
+ }
+ }
+
+ switch (atoi(argv[5]))
+ {
+ case 0:
+ DEBUG_PRINT("\n No Sink");
+ encoder_context->outputBufferFile = NULL;
+ break;
+ }
+
+ if (error != -1)
+ {
+ encoder_context->targetbitrate = atoi (argv[6]);
+ }
+
+ if ( error != -1 && (init_encoder (encoder_context) == -1 ))
+ {
+ DEBUG_PRINT("\n Init decoder fails ");
+ error = -1;
+ }
+ DEBUG_PRINT("\n Decoder open successfull");
+
+
+ /*Allocate input and output buffers*/
+ if (error != -1 && (allocate_buffer (0,encoder_context)== -1))
+ {
+ DEBUG_PRINT("\n Error in input Buffer allocation");
+ error = -1;
+ }
+
+ if (error != -1 && (allocate_buffer (1,encoder_context)== -1))
+ {
+ DEBUG_PRINT("\n Error in output Buffer allocation");
+ error = -1;
+ }
+
+
+ if (error != -1 && (start_encoding (encoder_context) == -1))
+ {
+ DEBUG_PRINT("\n Error in start decoding call");
+ error = -1;
+ }
+
+ if (error != -1 && (stop_encoding (encoder_context) == -1))
+ {
+ DEBUG_PRINT("\n Error in stop decoding call");
+ error = -1;
+ }
+
+ DEBUG_PRINT("\n De-init the decoder");
+ if ((deinit_encoder (encoder_context) == -1))
+ {
+ error = -1;
+ }
+
+
+ (void)free_buffer (INPUT_BUFFER,encoder_context);
+ (void)free_buffer (OUTPUT_BUFFER,encoder_context);
+
+ if (encoder_context->inputBufferFile != NULL)
+ {
+ fclose (encoder_context->inputBufferFile);
+ }
+ if (encoder_context->outputBufferFile != NULL)
+ {
+ fclose (encoder_context->outputBufferFile);
+ }
+ DEBUG_PRINT ("\n Total Number of frames decoded %d",total_frames);
+ DEBUG_PRINT("\n closing the driver");
+ free (encoder_context);
+
+ return error;
+}
+
+int init_encoder ( struct video_encoder_context *init_decode )
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_basecfg basecfg;
+ struct video_queue_context *queue_ptr = NULL;
+ struct venc_ratectrlcfg ratecrl;
+ pthread_mutexattr_t init_values;
+ struct venc_profile profile;
+ struct ven_profilelevel profilelevel;
+
+ DEBUG_PRINT("\n Before calling the open");
+
+ init_decode->video_driver_fd = open ("/dev/msm_vidc_enc", \
+ O_RDWR | O_NONBLOCK);
+
+
+
+ if (init_decode->video_driver_fd < 0)
+ {
+ DEBUG_PRINT("\n Open failed");
+ return -1;
+ }
+
+ basecfg.codectype = init_decode->codectype;
+ basecfg.dvs_height = 0;
+ basecfg.dvs_width = 0;
+ basecfg.fps_den = init_decode->fps_den;
+ basecfg.fps_num = init_decode->fps_num;
+ basecfg.input_height = init_decode->input_height;
+ basecfg.input_width = init_decode->input_width;
+ basecfg.inputformat = init_decode->inputformat;
+ basecfg.targetbitrate = init_decode->targetbitrate;
+
+ /*Initialize Decoder with codec type and resolution*/
+ ioctl_msg.in = &basecfg;
+ ioctl_msg.out = NULL;
+
+ if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_BASE_CFG,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Set base config type failed");
+ return -1;
+ }
+
+ /*Initialize Decoder with codec type and resolution*/
+ DEBUG_PRINT ("\n Switch off rate control");
+ ioctl_msg.in = &ratecrl;
+ ioctl_msg.out = NULL;
+ ratecrl.rcmode = VEN_RC_OFF;
+ if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Set rate control failed");
+ return -1;
+ }
+
+ if (basecfg.codectype == VEN_CODEC_H264)
+ {
+ DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
+ ioctl_msg.in = &profile;
+ ioctl_msg.out = NULL;
+ profile.profile = VEN_PROFILE_H264_BASELINE;
+ if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
+ return -1;
+ }
+
+ DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
+ ioctl_msg.in = &profilelevel;
+ ioctl_msg.out = NULL;
+ profilelevel.level = VEN_LEVEL_H264_1p1;
+ if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
+ return -1;
+ }
+
+ if (basecfg.input_width > 720)
+ {
+ DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
+ ioctl_msg.in = &profile;
+ ioctl_msg.out = NULL;
+ profile.profile = VEN_PROFILE_H264_HIGH;
+ if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
+ return -1;
+ }
+
+ DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
+ ioctl_msg.in = &profilelevel;
+ ioctl_msg.out = NULL;
+ profilelevel.level = VEN_LEVEL_H264_3p1;
+ if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
+ return -1;
+ }
+ }
+ }
+
+ DEBUG_PRINT("\n Query Input bufffer requirements");
+ /*Get the Buffer requirements for input and output ports*/
+
+
+
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = &init_decode->input_buffer;
+
+ if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Requesting for input buffer requirements failed");
+ return -1;
+ }
+
+ DEBUG_PRINT("\n input Size=%d min count =%d actual count = %d", \
+ (int)init_decode->input_buffer.datasize,\
+ (int)init_decode->input_buffer.mincount,\
+ (int)init_decode->input_buffer.actualcount);
+
+
+ ioctl_msg.in = &init_decode->input_buffer;
+ ioctl_msg.out = NULL;
+ init_decode->input_buffer.actualcount = init_decode->input_buffer.mincount + 2;
+
+ if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Set Buffer Requirements Failed");
+ return -1;
+ }
+
+
+ DEBUG_PRINT("\n Query output bufffer requirements");
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = &init_decode->output_buffer;
+
+ if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Requesting for output buffer requirements failed");
+ return -1;
+ }
+
+ DEBUG_PRINT("\n output Size=%d min count =%d actual count = %d", \
+ (int)init_decode->output_buffer.datasize,\
+ (int)init_decode->output_buffer.mincount,\
+ (int)init_decode->output_buffer.actualcount);
+
+ /*Create Queue related data structures*/
+ queue_ptr = &init_decode->queue_context;
+ queue_ptr->commandq_size = 50;
+ queue_ptr->dataq_size = 50;
+
+ sem_init(&queue_ptr->sem_message,0, 0);
+ sem_init(&init_decode->sem_synchronize,0, 0);
+
+ pthread_mutexattr_init (&init_values);
+ pthread_mutex_init (&queue_ptr->mutex,&init_values);
+ pthread_mutex_init (&read_lock,&init_values);
+ DEBUG_PRINT("\n create Queues");
+ queue_ptr->ptr_cmdq = (struct video_msgq*) \
+ calloc (sizeof (struct video_msgq),
+ queue_ptr->commandq_size);
+ queue_ptr->ptr_dataq = (struct video_msgq*) \
+ calloc (sizeof (struct video_msgq),
+ queue_ptr->dataq_size
+ );
+
+ if ( queue_ptr->ptr_cmdq == NULL ||
+ queue_ptr->ptr_dataq == NULL
+ )
+ {
+ return -1;
+ }
+ DEBUG_PRINT("\n create Threads");
+ /*Create two threads*/
+ if ( (pthread_create (&init_decode->videothread_id,NULL,video_thread,
+ init_decode) < 0) ||
+ (pthread_create (&init_decode->asyncthread_id,NULL,async_thread,
+ init_decode) < 0)
+ )
+ {
+ return -1;
+ }
+
+ return 1;
+}
+
+
+
+int free_buffer ( unsigned int buffer_dir,
+ struct video_encoder_context *encoder_context
+ )
+{
+ unsigned int buffercount = 0,i=0;
+ struct venc_bufferpayload **ptemp = NULL;
+
+ if (encoder_context == NULL)
+ {
+ return -1;
+ }
+
+ if (buffer_dir == INPUT_BUFFER && encoder_context->ptr_inputbuffer)
+ {
+ buffercount = encoder_context->input_buffer.actualcount;
+ ptemp = encoder_context->ptr_inputbuffer;
+
+ for (i=0;i<buffercount;i++)
+ {
+ if (ptemp [i])
+ {
+ if (ptemp [i]->fd != -1)
+ {
+ munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size);
+ ptemp [i]->pbuffer = NULL;
+ close (ptemp [i]->fd);
+ }
+ free (ptemp [i]);
+ ptemp [i] = NULL;
+ }
+ }
+ free (encoder_context->ptr_inputbuffer);
+ encoder_context->ptr_inputbuffer = NULL;
+ }
+ else if ( buffer_dir == OUTPUT_BUFFER && encoder_context->ptr_outputbuffer )
+ {
+ buffercount = encoder_context->output_buffer.actualcount;
+ ptemp = encoder_context->ptr_outputbuffer;
+
+ if (ptemp)
+ {
+ for (i=0;i<buffercount;i++)
+ {
+ if (ptemp [i])
+ {
+ if (ptemp [i]->fd != -1)
+ {
+ munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size);
+ ptemp [i]->pbuffer = NULL;
+ close (ptemp [i]->fd);
+ }
+ free (ptemp [i]);
+ ptemp [i] = NULL;
+ }
+ }
+ free (ptemp);
+ encoder_context->ptr_outputbuffer = NULL;
+ }
+ }
+
+ return 1;
+}
+
+int allocate_buffer ( unsigned int buffer_dir,
+ struct video_encoder_context *encoder_context
+ )
+{
+ struct venc_bufferpayload **ptemp = NULL;
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ unsigned int buffercount = 0,i=0,alignedsize=0;
+ unsigned int buffersize = 0;
+
+ if ( encoder_context == NULL)
+ {
+ DEBUG_PRINT ("\nallocate_buffer: context is NULL");
+ return -1;
+ }
+
+ if ( buffer_dir == INPUT_BUFFER )
+ {
+ /*Check if buffers are allocated*/
+ if (encoder_context->ptr_inputbuffer != NULL)
+ {
+ DEBUG_PRINT ("\nallocate_buffer: encoder_context->ptr_inputbuffer is set");
+ return -1;
+ }
+
+ buffercount = encoder_context->input_buffer.actualcount;
+ alignedsize = encoder_context->input_buffer.alignment;
+ buffersize = encoder_context->input_buffer.datasize;
+ buffersize = (buffersize + alignedsize) & (~alignedsize);
+ }
+ else if (buffer_dir == OUTPUT_BUFFER)
+ {
+ /*Check if buffers are allocated*/
+ if (encoder_context->ptr_outputbuffer != NULL)
+ {
+ DEBUG_PRINT ("\nallocate_buffer: Double allcoate output");
+ return -1;
+ }
+
+ buffercount = encoder_context->output_buffer.actualcount;
+ alignedsize = encoder_context->output_buffer.alignment;
+ buffersize = encoder_context->output_buffer.datasize;
+ buffersize = (buffersize + alignedsize) & (~alignedsize);
+
+ }
+ else
+ {
+ DEBUG_PRINT ("\nallocate_buffer: Wrong buffer directions");
+ return -1;
+ }
+
+ ptemp = (struct venc_bufferpayload **)\
+ calloc (sizeof (struct venc_bufferpayload *),buffercount);
+
+ if (ptemp == NULL)
+ {
+ DEBUG_PRINT ("\nallocate_buffer: venc_bufferpayload failure");
+ return -1;
+ }
+
+
+ if (buffer_dir == OUTPUT_BUFFER)
+ {
+ DEBUG_PRINT ("\nallocate_buffer: OUT");
+ encoder_context->ptr_outputbuffer = ptemp;
+ }
+ else
+ {
+ DEBUG_PRINT ("\nallocate_buffer: IN");
+ encoder_context->ptr_inputbuffer = ptemp;
+ }
+
+ /*Allocate buffer headers*/
+ for (i=0; i< buffercount; i++)
+ {
+ ptemp [i] = (struct venc_bufferpayload*)\
+ calloc (sizeof (struct venc_bufferpayload),1);
+
+ if (ptemp [i] == NULL)
+ {
+ DEBUG_PRINT ("\nallocate_buffer: ptemp [i] calloc failure");
+ return -1;
+ }
+ ptemp [i]->fd = -1;
+ }
+
+ for (i=0; i< buffercount; i++)
+ {
+ ptemp [i]->fd = open ("/dev/pmem_adsp",O_RDWR);
+
+ if (ptemp [i]->fd < 0)
+ {
+ DEBUG_PRINT ("\nallocate_buffer: open pmem_adsp failed");
+ return -1;
+ }
+
+ ptemp [i]->pbuffer = mmap(NULL,clp2(buffersize),PROT_READ|PROT_WRITE,
+ MAP_SHARED,ptemp [i]->fd,0);
+ DEBUG_PRINT ("\n pmem fd = %d virt addr = %p",ptemp [i]->fd,\
+ ptemp [i]->pbuffer);
+ if (ptemp [i]->pbuffer == MAP_FAILED)
+ {
+ ptemp [i]->pbuffer = NULL;
+ DEBUG_PRINT ("\nallocate_buffer: MMAP failed");
+ return -1;
+ }
+ ptemp [i]->sz = buffersize;
+ ptemp [i]->maped_size = clp2 (buffersize);
+
+ ioctl_msg.in = ptemp [i];
+ ioctl_msg.out = NULL;
+
+ if (buffer_dir == OUTPUT_BUFFER)
+ {
+ if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,
+ &ioctl_msg) < 0)
+ {
+ DEBUG_PRINT ("\nallocate_buffer: Set Output Buffer IOCTL failed");
+ return -1;
+ }
+ }
+ else
+ {
+ if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER,
+ &ioctl_msg) < 0)
+ {
+ DEBUG_PRINT ("\nallocate_buffer: Set input Buffer IOCTL failed");
+ return -1;
+ }
+ }
+
+ }
+ DEBUG_PRINT ("\nallocate_buffer: Success");
+ return 1;
+}
+
+
+
+int start_encoding (struct video_encoder_context *encoder_context)
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_buffer enc_buffer;
+ unsigned int i = 0;
+ unsigned int data_len =0;
+
+
+ if (encoder_context == NULL)
+ {
+ return -1;
+ }
+
+ if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_START,
+ NULL) < 0)
+ {
+ DEBUG_PRINT("\n Start failed");
+ return -1;
+ }
+
+ DEBUG_PRINT("\n Start Issued successfully waiting for Start Done");
+ /*Wait for Start command response*/
+ sem_wait (&encoder_context->sem_synchronize);
+
+ /*Push output Buffers*/
+ i = 0;
+ while (i < encoder_context->output_buffer.actualcount)
+ {
+ enc_buffer.clientdata = (void *)encoder_context->ptr_outputbuffer [i];
+ enc_buffer.flags = 0;
+ enc_buffer.sz = encoder_context->ptr_outputbuffer [i]->sz;
+ enc_buffer.len = 0;
+ enc_buffer.ptrbuffer = encoder_context->ptr_outputbuffer [i]->pbuffer;
+ enc_buffer.offset = 0;
+ enc_buffer.timestamp = 0;
+
+ DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata);
+ ioctl_msg.in = &enc_buffer;
+ ioctl_msg.out = NULL;
+
+ if (ioctl (encoder_context->video_driver_fd,
+ VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n fill output frame failed");
+ return -1;
+ }
+ i++;
+ }
+
+
+ /*push input buffers*/
+ i = 0;
+ while (i < encoder_context->input_buffer.actualcount)
+ {
+ DEBUG_PRINT("\n Read Frame from File");
+
+ enc_buffer.clientdata = (void *)encoder_context->ptr_inputbuffer [i];
+ enc_buffer.flags = 0;
+ enc_buffer.sz = encoder_context->ptr_inputbuffer [i]->sz;
+ enc_buffer.len = 0;
+ enc_buffer.ptrbuffer = encoder_context->ptr_inputbuffer [i]->pbuffer;
+ enc_buffer.offset = 0;
+ enc_buffer.timestamp = total_frames *
+ ((encoder_context->fps_den * 1000000)/encoder_context->fps_num);
+ enc_buffer.len = (encoder_context->input_height *
+ encoder_context->input_width *3)/2;
+ data_len = read_frame ( enc_buffer.ptrbuffer,
+ enc_buffer.len,
+ encoder_context->inputBufferFile);
+ if (data_len == 0)
+ {
+ DEBUG_PRINT("\n Length is zero error");
+ return -1;
+ }
+ enc_buffer.len = data_len;
+ DEBUG_PRINT("\n Read Frame from File szie = %d",(int)data_len);
+
+ DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata);
+ ioctl_msg.in = &enc_buffer;
+ ioctl_msg.out = NULL;
+
+ if (ioctl (encoder_context->video_driver_fd,
+ VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Encode input frame failed");
+ return -1;
+ }
+ total_frames++;
+ i++;
+ }
+ DEBUG_PRINT ("\n Wait for EOS");
+ /*Wait for EOS or Error condition*/
+ sem_wait (&encoder_context->sem_synchronize);
+ DEBUG_PRINT ("\n Reached EOS");
+
+ return 1;
+}
+
+int stop_encoding (struct video_encoder_context *encoder_context)
+{
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_bufferflush buffer_flush;
+
+ if (encoder_context == NULL)
+ {
+ return -1;
+ }
+ buffer_flush.flush_mode = VEN_FLUSH_INPUT;
+ ioctl_msg.in = &buffer_flush;
+ ioctl_msg.out = NULL;
+
+ if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH,
+ &ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Flush input failed");
+ }
+ else
+ {
+ sem_wait (&encoder_context->sem_synchronize);
+ }
+
+ buffer_flush.flush_mode = VEN_FLUSH_OUTPUT;
+ ioctl_msg.in = &buffer_flush;
+ ioctl_msg.out = NULL;
+
+ if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH,
+ &ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Flush output failed");
+ }
+ else
+ {
+ sem_wait (&encoder_context->sem_synchronize);
+ }
+
+ DEBUG_PRINT("\n Stop VEN_IOCTL_CMD_STOP");
+ if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_STOP,NULL) < 0)
+ {
+ DEBUG_PRINT("\n Stop failed");
+ }
+ else
+ {
+ sem_wait (&encoder_context->sem_synchronize);
+ }
+ return 1;
+}
+
+int deinit_encoder (struct video_encoder_context *init_decode)
+{
+ if (init_decode == NULL)
+ {
+ return -1;
+ }
+
+ /*Close the driver*/
+ if (init_decode->video_driver_fd != -1)
+ {
+ close (init_decode->video_driver_fd);
+ }
+
+ if (init_decode->queue_context.ptr_cmdq)
+ {
+ free (init_decode->queue_context.ptr_cmdq);
+ init_decode->queue_context.ptr_cmdq = NULL;
+ }
+
+ if (init_decode->queue_context.ptr_dataq)
+ {
+ free (init_decode->queue_context.ptr_dataq);
+ init_decode->queue_context.ptr_dataq = NULL;
+ }
+
+ sem_destroy (&init_decode->queue_context.sem_message);
+ sem_destroy (&init_decode->sem_synchronize);
+
+ pthread_mutex_destroy(&init_decode->queue_context.mutex);
+ pthread_mutex_destroy (&read_lock);
+
+ return 1;
+}
+
+static void* video_thread (void *context)
+{
+ struct video_encoder_context *encoder_context = NULL;
+ struct video_msgq *queueitem = NULL;
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ struct venc_bufferpayload *tempbuffer = NULL;
+ struct venc_buffer enc_buffer;
+ unsigned int data_len =0;
+
+
+ if (context == NULL)
+ {
+ DEBUG_PRINT("\n video thread recieved NULL context");
+ return NULL;
+ }
+ encoder_context = (struct video_encoder_context *) context;
+
+ /* Thread function which will accept commands from async thread
+ * or main thread
+ */
+ while (1)
+ {
+ queueitem = queue_get_cmd (&encoder_context ->queue_context);
+ if (queueitem != NULL)
+ {
+ switch (queueitem->cmd)
+ {
+ case VEN_MSG_START:
+ DEBUG_PRINT("\n recived start done command");
+ sem_post (&encoder_context->sem_synchronize);
+ break;
+
+ case VEN_MSG_STOP:
+ DEBUG_PRINT("\n recieved stop done");
+ sem_post (&encoder_context->sem_synchronize);
+ break;
+
+ case VEN_MSG_INPUT_BUFFER_DONE:
+
+ tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata;
+ if (tempbuffer == NULL)
+ {
+ DEBUG_PRINT("\n FATAL ERROR input buffer address is bad");
+ sem_post (&encoder_context->sem_synchronize);
+ break;
+ }
+ tempbuffer->filled_len = (encoder_context->input_height *
+ encoder_context->input_width *3)/2;
+
+ data_len = read_frame ( tempbuffer->pbuffer,
+ tempbuffer->filled_len,
+ encoder_context->inputBufferFile);
+
+ if (data_len == 0)
+ {
+ DEBUG_PRINT ("\n End of stream reached");
+ sem_post (&encoder_context->sem_synchronize);
+ break;
+ }
+ enc_buffer.clientdata = (void *)tempbuffer;
+ enc_buffer.flags = 0;
+ enc_buffer.ptrbuffer = tempbuffer->pbuffer;
+ enc_buffer.sz = tempbuffer->sz;
+ enc_buffer.len = tempbuffer->filled_len;
+ enc_buffer.offset = 0;
+ enc_buffer.timestamp = total_frames *
+ ((encoder_context->fps_den * 1000000)/encoder_context->fps_num);
+
+ /*TODO: Time stamp needs to be updated*/
+ ioctl_msg.in = &enc_buffer;
+ ioctl_msg.out = NULL;
+ total_frames++;
+ if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,
+ &ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Decoder frame failed");
+ sem_post (&encoder_context->sem_synchronize);
+ }
+ DEBUG_PRINT("\n Input buffer done send next buffer current value = %d",\
+ total_frames);
+ break;
+
+ case VEN_MSG_OUTPUT_BUFFER_DONE:
+
+ tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata;
+ if (tempbuffer == NULL)
+ {
+ DEBUG_PRINT("\n FATAL ERROR input buffer address is bad");
+ sem_post (&encoder_context->sem_synchronize);
+ break;
+ }
+
+ if (encoder_context->outputBufferFile != NULL)
+ {
+ fwrite (tempbuffer->pbuffer,1,tempbuffer->filled_len,
+ encoder_context->outputBufferFile);
+ }
+
+
+ DEBUG_PRINT("\n recieved output buffer consume outbuffer");
+ DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\
+ tempbuffer->pbuffer);
+ enc_buffer.clientdata = (void *)tempbuffer;
+ enc_buffer.flags = 0;
+ enc_buffer.sz = tempbuffer->sz;
+ enc_buffer.len = 0;
+ enc_buffer.ptrbuffer = tempbuffer->pbuffer;
+ enc_buffer.offset = 0;
+ enc_buffer.timestamp = 0;
+
+ ioctl_msg.in = &enc_buffer;
+ ioctl_msg.out = NULL;
+
+ if (ioctl (encoder_context->video_driver_fd,
+ VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Decoder frame failed");
+ return NULL;
+ }
+
+ break;
+
+ case VEN_MSG_FLUSH_INPUT_DONE:
+ DEBUG_PRINT("\n Flush input complete");
+ sem_post (&encoder_context->sem_synchronize);
+ break;
+
+ case VEN_MSG_FLUSH_OUPUT_DONE:
+ DEBUG_PRINT("\n Flush output complete");
+ sem_post (&encoder_context->sem_synchronize);
+ break;
+ }
+
+ if (queueitem->cmd == VEN_MSG_STOP)
+ {
+ DEBUG_PRINT("\n Playback has ended thread will exit");
+ return NULL;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT("\n Error condition recieved NULL from Queue");
+ }
+
+ }
+}
+
+static void* async_thread (void *context)
+{
+ struct video_encoder_context *encoder_context = NULL;
+ struct video_msgq queueitem ;
+ struct venc_msg venc_msg;
+ struct venc_bufferpayload *tempbuffer = NULL;
+ struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ int result = -1;
+
+ if (context == NULL)
+ {
+ DEBUG_PRINT("\n aynsc thread recieved NULL context");
+ return NULL;
+ }
+ encoder_context = (struct video_encoder_context *) context;
+ DEBUG_PRINT("\n Entering the async thread");
+
+ while (1)
+ {
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&venc_msg;
+ DEBUG_PRINT ("\n Sizeof venc_msginfo = %d ",sizeof (venc_msg));
+ DEBUG_PRINT("\n Address of Venc msg in async thread %p",\
+ ioctl_msg.out);
+ if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,\
+ (void*)&ioctl_msg) < 0)
+ {
+ DEBUG_PRINT("\n Error in ioctl read next msg");
+ }
+ else
+ {
+ switch (venc_msg.msgcode)
+ {
+ case VEN_MSG_START:
+ case VEN_MSG_STOP:
+ case VEN_MSG_INDICATION:
+ DEBUG_PRINT("\nSTOP/START Indiacation");
+ queueitem.cmd = venc_msg.msgcode;
+ queueitem.status = venc_msg.statuscode;
+ queueitem.clientdata = NULL;
+ break;
+
+ case VEN_MSG_INPUT_BUFFER_DONE:
+ DEBUG_PRINT("\nINPUT buffer done Indiacation");
+ queueitem.cmd = venc_msg.msgcode;
+ queueitem.status = venc_msg.statuscode;
+ queueitem.clientdata = (void *)venc_msg.buf.clientdata;
+ DEBUG_PRINT("\nInput Client data pointer is %p",queueitem.clientdata);
+ tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata;
+ DEBUG_PRINT ("\n Input Address of tempbuffer %p",tempbuffer);
+ tempbuffer->filled_len = venc_msg.buf.len;
+ DEBUG_PRINT ("\n Input value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len);
+ break;
+ case VEN_MSG_OUTPUT_BUFFER_DONE:
+ DEBUG_PRINT("\nOUPUT buffer done Indiacation");
+ queueitem.cmd = venc_msg.msgcode;
+ queueitem.status = venc_msg.statuscode;
+ queueitem.clientdata = (void *)venc_msg.buf.clientdata;
+ DEBUG_PRINT("\nOutput Client data pointer is %p",queueitem.clientdata);
+ tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata;
+ DEBUG_PRINT ("\n Output Address of tempbuffer %p",tempbuffer);
+ tempbuffer->filled_len = venc_msg.buf.len;
+ DEBUG_PRINT ("\n Output value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len);
+ break;
+
+ default:
+ DEBUG_PRINT("\nIn Default of get next message %d",(int)venc_msg.msgcode);
+ queueitem.cmd = venc_msg.msgcode;
+ queueitem.status = venc_msg.statuscode;
+ queueitem.clientdata = NULL;
+ break;
+ }
+ result = queue_post_cmdq (&encoder_context->queue_context,&queueitem);
+ while (result == 0)
+ {
+ result = queue_post_cmdq (&encoder_context->queue_context,&queueitem);
+ }
+
+ if (result == -1)
+ {
+ DEBUG_PRINT("\n FATAL ERROR WITH Queue");
+ }
+ }
+ if (venc_msg.msgcode == VEN_MSG_STOP)
+ {
+ /*Thread can exit at this point*/
+ return NULL;
+ }
+ }
+}
+
+
+static unsigned int read_frame (unsigned char *dataptr, unsigned int length,
+ FILE * inputBufferFile)
+{
+
+ unsigned int readOffset = 0;
+ int bytes_read = 0;
+ unsigned int code = 0;
+ int found = 0;
+
+ DEBUG_PRINT ("\n Inside the readframe");
+
+ if (dataptr == NULL && length == 0)
+ {
+ DEBUG_PRINT ("\n dataptr = %p length = %d",dataptr,(int)length);
+ return 0;
+ }
+
+ pthread_mutex_lock(&read_lock);
+ bytes_read = fread(&dataptr[readOffset],1,length,inputBufferFile);
+ pthread_mutex_unlock(&read_lock);
+
+ return bytes_read;
+}